There are some inconsistency in your code (2to4decoder arguments are x,y or ce0, ce1?) so I will answer assuming the following signatures for your modules: (control is active low, as you designed)
ram16x4 (
input [3:0] adrs,
inout [3:0] data,
input chip_en,
input write_en,
input output_en
);
module 2to4decoder (
input a5,
input a4,
ouput _ce0,
ouput _ce1,
ouput _ce2,
ouput _ce3
};
The solution is based on 2 simple techniques. One for expanding the data (from 4 to 8) and one foe expanding the address space (from 16 to 64):
- data - In order to expand the data (lets say to 16x8 memory) you will need two instances that take the same control signals and different part of the data - one takes bits [3:0] and the other bits [7:4]. Every write and read is performed on both instances.
- address space - In order to expand the address space (lets say to 64x4 memory) you should use the 2to4 decoder. This way addresses 0-15 are mapped to instance 0, addresses 16-31 mapped to instance 1 and so on... Every write or read is performed on only one instance, according to the address MSBs.
saying all that, the 64x8 solution is based on combining the 2 concepts above and smay look like this: (it can be more elegant when using generate for, but thats another story)
module ram64x8(
input [5:0] adrs,
inout [7:0] data,
input chip_en, write_en, output_en );
wire ce0, ce1, ce2, ce3;
2to4decoder decode (
.a5 (adrs[5]),
.a4 (adrs[4]),
._ce0 (~ce0),
._ce1 (~ce1),
._ce2 (~ce2),
._ce3 (~ce3) );
ram16x4 mem_0_0(
.adrs (adrs[3:0]),
.data (data[3:0]),
.chip_en (ce0),
.write_en (write_en),
.output_en (output_en) );
ram16x4 mem_0_1(
.adrs (adrs[3:0]),
.data (data[7:4]),
.chip_en (ce0),
.write_en (write_en),
.output_en (output_en) );
ram16x4 mem_1_0(
.adrs (adrs[3:0]),
.data (data[3:0]),
.chip_en (ce1),
.write_en (write_en),
.output_en (output_en) );
ram16x4 mem_1_1(
.adrs (adrs[3:0]),
.data (data[7:4]),
.chip_en (ce1),
.write_en (write_en),
.output_en (output_en) );
ram16x4 mem_2_0(
.adrs (adrs[3:0]),
.data (data[3:0]),
.chip_en (ce2),
.write_en (write_en),
.output_en (output_en) );
ram16x4 mem_2_1(
.adrs (adrs[3:0]),
.data (data[7:4]),
.chip_en (ce2),
.write_en (write_en),
.output_en (output_en) );
ram16x4 mem_3_0(
.adrs (adrs[3:0]),
.data (data[3:0]),
.chip_en (ce3),
.write_en (write_en),
.output_en (output_en) );
ram16x4 mem_3_1(
.adrs (adrs[3:0]),
.data (data[7:4]),
.chip_en (ce3),
.write_en (write_en),
.output_en (output_en) );
endmodule
module ram64x8might be to the question, even if it is only instantiating a few 16x4 blocks.