Verilog Register File

0

Escribí un código verilog para un registro de 4 por 9 bits:

module reg_file(input rst,
            input clk,
            input wr_en,
            input rd_en,
            input [1:0]rd0_addr,
            input [1:0]rd1_addr,
            input [1:0]wr_addr,
            input [8:0]wr_data,
            output reg [8:0]rd0_data,
            output reg [8:0]rd1_data);

    reg [8:0]mem[3:0];
    integer i;

    always @(posedge rst or negedge clk)
    begin
        if (rst) begin
            for (i=0; i<4; i=i+1)
                mem[i]=0;
        end
        else if (wr_en) begin
            mem[wr_addr]=wr_data;
        end
        else (rd_en) begin
            assign rd0_data = mem[rd0_addr];
            assign rd1_data = mem[rd1_addr];
        end
    end
endmodule

pero utilizando iverilog para verificar si hay algún problema, dice:

26: syntax error
27: Syntax in assignment statement l-value.
30: syntax error

Parece que no entiendo por qué recibo estos errores, ¿puede alguien ayudarme?

También necesito encontrar vectores de prueba para probar todos los resultados posibles del archivo de registro. ¿Alguien tiene alguna sugerencia sobre la mejor manera de hacerlo?

    
pregunta dms94

2 respuestas

3

Esos números en la parte delantera de los mensajes de error son números de línea. Abra su archivo verilog en un editor de texto que muestre números de línea y averigüe dónde están.

Un problema que noté estaba en la línea:

else (rd_en) begin

No puede tener una condición después de else sin otra palabra clave if .

else if (rd_en) begin
    
respondido por el Justin
1

Afaics hay tres problemas con ese código verilog.

  1. falta if antes de (rd_en) , como señaló @Justin.

  2. las declaraciones assign dentro de los bloques siempre son falsas. (Hay algo que se denomina asignaciones continuas de procedimiento y la sintaxis que está utilizando aquí es una asignación continua de este tipo, pero está bastante seguro de que no quiso decir eso).

  3. estás usando asignaciones de bloqueo en un bloque siempre sincronizado, lo que significa que este código experimentará condiciones de carrera en la simulación. Ver por ejemplo Para obtener más detalles, este documento . En este caso, las asignaciones a la misma variable son exclusivas de todos modos, así que simplemente cambiando = a <= soluciona este problema:

    module reg_file(input rst,
                input clk,
                input wr_en,
                input rd_en,
                input [1:0] rd0_addr,
                input [1:0] rd1_addr,
                input [1:0] wr_addr,
                input [8:0] wr_data,
                output reg [8:0] rd0_data,
                output reg [8:0] rd1_data);
    
        reg [8:0] mem [3:0];
        integer i;
    
        always @(posedge rst or negedge clk)
        begin
            if (rst) begin
                for (i=0; i<4; i=i+1)
                    mem[i] <= 0;
            end
            else if (wr_en) begin
                mem[wr_addr] <= wr_data;
            end
            else if (rd_en) begin
                rd0_data <= mem[rd0_addr];
                rd1_data <= mem[rd1_addr];
            end
        end
    endmodule
    

PS: no es un problema real para las memorias que solo tienen 4 palabras de profundidad, pero para la mayoría de las arquitecturas de FPGA, el restablecimiento de las memorias inhibirá la creación de instancias de recursos de memoria dedicados y producirá un resultado de síntesis mucho mayor.

PPS: posedge rst or negedge clk es muy inusual (pero sigue siendo Verilog válido, por supuesto). ¿Estás seguro de que no quieres decir posedge clk or negedge rst ?

    
respondido por el CliffordVienna

Lea otras preguntas en las etiquetas