0

So for an assignment I have to create a memory module using existing memory modules. I need to turn a module that stores ram64x8 to a ram128x16. I am losing later half of my stored data when I attempt to read from the memory, or when I write. I'm not sure where my problem is. I do know it should be in my module ram128x16 since I wrote a test bench for the ram64x8 module and everything writes and reads properly. Can anyone figure out why when I attempt to store FFFF into the data, it only reads out 00FF? So my thought process was since I need 2 of the modules why not just do what the 16x8 module did, split address and data in half. is this not the case?

I updated the current code I have with what I have done according to the tips here, But i'm still at a loss on how to manage the addresses.

these are the modules

module ram128x16(
  input [6:0] adrs,
  inout [15:0] data,
  input _ce, _we, _oe

);
  reg [3:0] _cee;

  ram64x8 u1(adrs[5:0], data[15:8], _cee[0], _we, _oe);
  ram64x8 u2(adrs[5:0], data[7:0], _cee[0], _we, _oe);

  ram64x8 u3(adrs[5:0], data[15:8], _cee[1], _we, _oe);
  ram64x8 u4(adrs[5:0], data[7:0], _cee[1], _we, _oe);


  ram64x8 u5(adrs[5:0], data[15:8], _cee[2], _we, _oe);
  ram64x8 u6(adrs[5:0], data[7:0], _cee[2], _we, _oe);


  ram64x8 u7(adrs[5:0], data[15:8], _cee[3], _we, _oe);
  ram64x8 u8(adrs[5:0], data[7:0], _cee[3], _we, _oe);


  //1 - to - 2 decode
  always @ (*)
begin
    if(_ce == 0)
      case(adrs[6:5])
    0: _cee = 4'b1110;
    1: _cee = 4'b1101;
    2: _cee = 4'b1011;
    3: _cee = 4'b0111;
    default: _cee = 4'hf;
    endcase
    else
        _cee = 4'hf;
end
  endmodule


module ram64x8(
    input [5:0] adrs,
    inout [7:0] data,
    input _ce, _we, _oe
);
  reg [3:0] _cee;
ram16x8 u1(adrs[3:0], data, _cee[0], _we, _oe);
ram16x8 u2(adrs[3:0], data, _cee[1], _we, _oe);
ram16x8 u3(adrs[3:0], data, _cee[2], _we, _oe);
ram16x8 u4(adrs[3:0], data, _cee[3], _we, _oe);
//2 - to - 4 decode
always @ (*)
begin
    if(_ce == 0)
    case(adrs[5:4])
    0: _cee = 4'b1110;
    1: _cee = 4'b1101;
    2: _cee = 4'b1011;
    3: _cee = 4'b0111;
    default: _cee = 4'hf;
    endcase
    else
        _cee = 4'hf;
end
endmodule

module ram16x8(
    input [3:0] adrs,
    inout [7:0] data,
    input _ce, _we, _oe
);

    ram16x4 u1(adrs, data[7:4], data[7:4], _ce, _we, _oe);
    ram16x4 u2(adrs, data[3:0], data[3:0], _ce, _we, _oe);

endmodule

module ram16x4(
    input [3:0] adrs,
    input [3:0] dataIn,
    output [3:0] dataOut,
    input _ce, _we, _oe
);
  reg [3:0] mem[0:15]; // 16 X 4 ram
assign dataOut = ~_ce & _we & ~_oe ? mem[adrs]:4'hz;
always@(*)
begin
if(_ce==0)
    if(_we == 0 && _oe ==1)
        mem[adrs] = dataIn;
end
endmodule

this is my test bench

module ram();

  reg [11:0] adrs;
  reg [15:0] content;
  reg _ce, _we, _oe;
  wire [15:0] data;
  assign data = ~_ce & ~_we & _oe ? content : 16'hz;
  ram128x16 u1(adrs, data, _ce,_we,_oe);
  initial begin
    $monitor ("%4d: adrs = %h _ce + %b _we = %b _oe = %b data =%h", $time, adrs, _ce, _we, _oe, data);

    adrs = 12'd0; 
    content = 16'd0;
    _ce = 1'b0; _we = 1'b0; _oe = 1'b1;
    #10
    _ce = 1'b1; _we = 1'b1; _oe = 1'b1;
    #50
    adrs = 12'b011111; 
    content = 16'hFFFF;
    _ce = 1'b0; _we = 1'b0; _oe = 1'b1;
    #10
    _ce = 1'b1; _we = 1'b1; _oe = 1'b1;
    #40
    adrs = 12'b100000; 
    content = 8'd0387+127;
    _ce = 1'b0; _we = 1'b0; _oe = 1'b1;
    #10
    _ce = 1'b1; _we = 1'b1; _oe = 1'b1;
    #40
    adrs = 12'b110000; 
    content = 8'd0387-127;
    _ce = 1'b0; _we = 1'b0; _oe = 1'b1;
    #10
    _ce = 1'b1; _we = 1'b1; _oe = 1'b1;
    #40

    //read

    adrs = 12'b000000; 
    _ce = 1'b0; _we = 1'b1; _oe = 1'b0;
    #10
    _ce = 1'b1; _we = 1'b1; _oe = 1'b1;
    #50
    adrs = 12'b011111; 
    _ce = 1'b0; _we = 1'b1; _oe = 1'b0;
    #10
    _ce = 1'b1; _we = 1'b1; _oe = 1'b1;
    #40
    adrs = 12'b100000; 
    _ce = 1'b0; _we = 1'b1; _oe = 1'b0;
    #10
    _ce = 1'b1; _we = 1'b1; _oe = 1'b1;
    #40
    adrs = 12'b110000; 
    _ce = 1'b0; _we = 1'b1; _oe = 1'b0;
    #10
    _ce = 1'b1; _we = 1'b1; _oe = 1'b1;
    #40


    $finish;



end


endmodule
4
  • You used 2 ram64x8 to create ram128x8. Check your previous steps, you will get the idea. If you want you can write some code to create one more step to turn ram128x8 into ram128x16. Commented May 7, 2019 at 5:37
  • As you know, your RAM needs to have minimum width of 16 bits to store FFFF, but the RAM you tried to design has actual width of 8 bits, that is the main reason behind the loss of information. Commented May 7, 2019 at 6:23
  • I feel like I'm stepping in the wrong direction can you be a bit more specific in your hints? you said my actual width is 8 bits, but I increased data to 16 bits in the highest module didn't i? This was code provided to us as a base and the only part we had to write was the highest module, so I'm a bit fuzzy as to how it works since he also didn't really go through verilog that much Commented May 7, 2019 at 15:44
  • pastebin.com/RvBGyR3B this is sort of the direction I went into but I'm not sure if I am heading into the right direction Commented May 7, 2019 at 16:07

1 Answer 1

1

You need to start with some basic math.

You have a memory of 64x8 bits. That is 512 bits.
You need a memory of 128x16 bits. That is 2048 bits.

Thus you need four memories of 64x8 to get that number of bits.

You have to do two types of expansion:

  1. A width expansion to get from 8 bits wide to 16 bits wide.
  2. A depth expansion to get from 64 deep to 128 deep.

The first requires you to use memories in parallel.
The second requires you to use memories 'sequentially'.

In your code you have sort of done a width expansion by putting two memories in parallel. However your address bits are totally messed up.

After all that advice I leave the rest to you as I suspect this is home work.

Sign up to request clarification or add additional context in comments.

3 Comments

so I was working on it earlier today and I noticed that after getting some feedback here and I attempted to do exactly what you mentioned but I'm a bit confused as to how the 64x8 module runs the memory in parallel, do you mind explaining that to me? this is basically what i attempted to do after realizing that pastebin.com/eUiBGuqJ
I figured out my problem I was heading in the right direction but my test bench was incorrect
@Tekkundashi, by parallel he meens they share the same addressing but divide the data into two parts. Series means addressing of one is continuation of the other, but they share the same part of data. By just changing the numbering of the previous satates, you can do the job

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.