módulo Verilog RAM con Register File & Testbench

0

Estoy diseñando un módulo RAM con testbench en Verilog. Se supone que debe acceder a un archivo de registro (.dat) en el banco de pruebas y ejecutarlo a través de un módulo ALU. Hay 4 módulos (memory.v, alu.v, toplevel.v y testbench.v).

Mi problema es que cuando ejecuto ModelSIM no obtengo los resultados esperados.

'timescale 1ns/1ps

module testbench_lab3_reg();

reg clk;            
reg [4:0] Read_address;
reg [4:0] Write_address;
reg read_en; 
reg write_en;
wire [15:0] DataOut;
reg [15:0] memory [0:15];

assign DataOut = (read_en) ? memory[Read_address] : memory[Write_address];

lab3_reg dut(.clk(clk), .Read_address(Read_address), .Write_address(Write_address), .read_en(read_en), .write_en(write_en), .DataOut(DataOut));

always
begin
    clk = 1; #10; clk = 0; #10;
end

initial begin
$readmemb("memfile.dat", memory);

Read_address = 5'b00000; Write_address = 5'b01001; read_en = 1;  write_en = 0; #20;
Read_address = 5'b00000; Write_address = 5'b01001; read_en = 0;  write_en = 1; #20;

Read_address = 5'b00001; Write_address = 5'b01010; read_en = 1;  write_en = 0; #20;
Read_address = 5'b00001; Write_address = 5'b01010; read_en = 0;  write_en = 1; #20;

Read_address = 5'b00010; Write_address = 5'b01011; read_en = 1;  write_en = 0; #20;
Read_address = 5'b00010; Write_address = 5'b01011; read_en = 0;  write_en = 1; #20;

Read_address = 5'b00011; Write_address = 5'b01100; read_en = 1;  write_en = 0; #20;
Read_address = 5'b00011; Write_address = 5'b01100; read_en = 0;  write_en = 1; #20;

Read_address = 5'b00100; Write_address = 5'b01101; read_en = 1;  write_en = 0; #20;
Read_address = 5'b00100; Write_address = 5'b01101; read_en = 0;  write_en = 1; #20;

Read_address = 5'b01001; Write_address = 5'b00000; read_en = 1;  write_en = 0; #20;
Read_address = 5'b01010; Write_address = 5'b00000; read_en = 1;  write_en = 0; #20;
Read_address = 5'b01011; Write_address = 5'b00000; read_en = 1;  write_en = 0; #20;
Read_address = 5'b01100; Write_address = 5'b00000; read_en = 1;  write_en = 0; #20;
Read_address = 5'b01101; Write_address = 5'b00000; read_en = 1;  write_en = 0; #20;

$stop; 

end
endmodule

Sé que mi ALU funciona porque lo probé utilizando una RAM generada por MegaWizard. El siguiente es mi módulo ram:

module memory(
input clk,
 input [15:0] write_data,
input [4:0] raddress,
input [4:0] waddress,
input read_enable,
input write_enable,
 output [15:0] read_data);
reg [15:0] memory [0:15];
 reg [15:0] data_out;

assign read_data = data_out;

always @(posedge clk) 
 begin
    if (write_enable) 
        memory[waddress] <= write_data;
      if (read_enable)
            data_out <= memory[raddress];
end

endmodule

El siguiente es mi módulo de nivel superior, que crea una instancia de la ALU y la RAM:

module lab3_reg(
            input clk,
            input [4:0] Read_address,
            input [4:0] Write_address,
            input read_en,
            input write_en,
            output [15:0] DataOut
            );


wire zero;
wire signed [3:0] y;
alu inst1(DataOut [12:9], DataOut [8:5], DataOut [15:13], y, zero);

wire signed [15:0] y_signed;
assign y_signed = y;

wire [15:0] data;
assign data = DataOut;
memory inst2(clk, y_signed, Read_address, Write_address, read_en, write_en, data);

endmodule

Estoy bastante seguro de que el problema está en mi banco de pruebas, pero he estado atormentándome por esto, por lo que cualquier ayuda sería increíble.

memfile.dat

0100000111100000
1100000111100000
1111111000000000
0001111111100000
0010000111100000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
    
pregunta davlovsky

1 respuesta

0

Puede ser que malinterprete algo, pero ¿dónde están las entradas para su módulo ALU? Entonces, creo que el primer problema en su estructura es que, en el caso de que no tenga entradas para ALU, escriba en la memoria valores desconocidos (U o Z, lo que tiene en la salida de ALU) cuando write_en está activo;

El segundo problema está en el módulo lab3_reg que tiene una asignación incorrecta en la línea assign data = DataOut; , debería ser assign DataOut = data; porque data es la salida del módulo interno que tiene "X" en el puerto ( controladores múltiples);

Y el último problema está en el módulo tesbench testbench_lab3_reg , en el que también tienes una mala asignación assign DataOut = (read_en) ? memory[Read_address] : memory[Write_address]; en esta línea. DataOut es la salida de su módulo superior, pero en la línea asigna otro valor, en el caso de que también obtenga "X" en el cable.

Trate de corregir los errores en la lógica de asignaciones para corregir y luego creo que su módulo funcionará bien.

P.S. Por cierto, ¿qué quieres obtener con la asignación de seguimiento assign DataOut = (read_en) ? memory[Read_address] : memory[Write_address]; cuando se genera DataOut ? Si desea utilizar un bus bidireccional, debe declararlo como inout en los módulos.

    
respondido por el Roman

Lea otras preguntas en las etiquetas