I have the task of designing a 8x8 bit memory in Verilog using CMOS.
Currently, I have the following:
- Bitcell - takes in signals sel (if its selected), rw (read = 0, write = 1) and input.
If sel=0, output is high impedance. If sel=1, it either reads, or writes (and outputs the written value).
- word_8 - Collection of 8 bitcells that also take in sel and rw (forwarded to each cell individually). 8 input and 8 output wires to each bitcell.
- decoder_3to8 - decoder thats supposed to take in an address, and select the word which is supposed to be read.
I have individual testbenches for all those, and they all pass without issues.
This is my 8x8 cell:
module memory_8x8 (
input[2:0] addr,
input[7:0] inp,
input op,
input select,
output[7:0] outp
);
wire[7:0] selected_cell;
decoder_3to8 decoder(
.valid(select),
.addr(addr),
.sel(selected_cell)
);
genvar i;
generate
for (i = 0; i < 8; i = i + 1) begin
word_8 word_instance(
.sel(selected_cell[i]),
.rw(op),
.inp(inp),
.outp(outp)
);
end
endgenerate
I have tried setting up a basicly testbench for this too.
Basically:
Write cell 0
Write cell 1
Read cell 0
select = 0;
op = 0;
addr = 3'b000;
inp = 8'b00000000;
expected_outp = 8'bXXXXXXXX;
#10;
// Stage 0
$display("Test stage 0 - Write to cell 0, write to cell 1, read cell 0\n");
// Write to cell 0
select = 1;
op = 1;
addr = 3'b000;
inp = 8'hAA;
expected_outp = inp;
#10;
if (outp !== expected_outp) begin
$display("Write to cell 0 FAILED at time %0t ns: Address %b, Expected %b, Got %b",
$time, addr, expected_outp, outp);
end else begin
$display("Write to cell 0 PASSED at time %0t ns: Address %b, Data %b",
$time, addr, outp);
end
// Write to cell 1
addr = 3'b001;
inp = 8'hBB;
expected_outp = inp;
#10;
if (outp !== expected_outp) begin
$display("Write to cell 1 FAILED at time %0t ns: Address %b, Expected %b, Got %b",
$time, addr, expected_outp, outp);
end else begin
$display("Write to cell 1 PASSED at time %0t ns: Address %b, Data %b",
$time, addr, outp);
end
// Read cell 0
op = 0;
addr = 3'b000;
expected_outp = 8'hAA;
#10;
if (outp !== expected_outp) begin
$display("Read cell 0 FAILED at time %0t ns: Address %b, Expected %b, Got %b",
$time, addr, expected_outp, outp);
end else begin
$display("Read cell 0 PASSED at time %0t ns: Address %b, Data %b",
$time, addr, outp);
end
select = 0;
#10;
// Read cell 2
op = 0;
addr = 3'b001;
expected_outp = 8'hBB;
#10;
if (outp !== expected_outp) begin
$display("Read cell 1 FAILED at time %0t ns: Address %b, Expected %b, Got %b",
$time, addr, expected_outp, outp);
end else begin
$display("Read cell 1 PASSED at time %0t ns: Address %b, Data %b",
$time, addr, outp);
end
This gives the following output:
Test stage 0 - Write to cell 0, write to cell 1, read cell 0
Selected cell: 00000001
Write to cell 0 PASSED at time 20000 ns: Address 000, Data 10101010
Selected cell: 00000010
Write to cell 1 PASSED at time 30000 ns: Address 001, Data 10111011
Selected cell: 00000001
Read cell 0 FAILED at time 40000 ns: Address 000, Expected 10101010, Got 10111011
Selected cell: 00000000
Read cell 1 FAILED at time 60000 ns: Address 001, Expected 10111011, Got zzzzzzzz
Here however, the value written to cell 1 seems to be saved in cell 0, while cell 1 doesn't.
Any ideas?