add Verilog design for fracturable 32k memory
This commit is contained in:
parent
42b5ea2cb1
commit
743167521a
|
@ -0,0 +1,371 @@
|
|||
//-----------------------------------------------------
|
||||
// Design Name : frac_mem_32k
|
||||
// File Name : frac_mem_32k.v
|
||||
// Function : A fracturable BRAM which can operate in 13 modes
|
||||
// - Single port RAM 512x64 bit
|
||||
// - Single port RAM 1024x32 bit
|
||||
// - Single port RAM 2048x16 bit
|
||||
// - Single port RAM 4096x8 bit
|
||||
// - Single port RAM 8192x4 bit
|
||||
// - Single port RAM 16384x2 bit
|
||||
// - Single port RAM 32768x1 bit
|
||||
// - Dual port RAM 1024x32
|
||||
// - Dual port RAM 2048x16 bit
|
||||
// - Dual port RAM 4096x8 bit
|
||||
// - Dual port RAM 8192x4 bit
|
||||
// - Dual port RAM 16384x2 bit
|
||||
// - Dual port RAM 32768x1 bit
|
||||
// Inspired by the dual port ram Verilog from
|
||||
// https://www.intel.com/content/www/us/en/programmable/support/support-resources/design-examples/design-software/vhdl/vhd-true-dual-port-ram-sclk.html
|
||||
// Coder : Xifan Tang
|
||||
//-----------------------------------------------------
|
||||
|
||||
module frac_mem_32k (
|
||||
input [0:14] addr_a,
|
||||
input [0:14] addr_b,
|
||||
input [0:31] data_a,
|
||||
input [0:31] data_b,
|
||||
input we_a,
|
||||
input we_b,
|
||||
output reg [0:31] q_a,
|
||||
output reg [0:31] q_b,
|
||||
input clk,
|
||||
input [0:3] mode);
|
||||
|
||||
reg [0:9] ram_a [0:31];
|
||||
reg [0:9] ram_b [0:31];
|
||||
|
||||
always @(posedge clk) begin
|
||||
// Operating mode: single port RAM 512 x 64
|
||||
if (4'b0000 == mode) begin
|
||||
if (we_a) begin
|
||||
ram_a[addr_a[0:8]] <= data_a;
|
||||
ram_b[addr_a[0:8]] <= data_b;
|
||||
q_a <= data_a;
|
||||
q_b <= data_b;
|
||||
end else begin
|
||||
q_a <= ram_a[addr_a[0:8]];
|
||||
q_b <= ram_b[addr_a[0:8]];
|
||||
end
|
||||
// Operating mode: single port RAM 1024 x 32
|
||||
end else if (4'b0001 == mode) begin
|
||||
if (we_a) begin
|
||||
ram_a[addr_a[0:9]] <= data_a;
|
||||
end else begin
|
||||
q_a <= ram_a[addr_a[0:9]];
|
||||
end
|
||||
// Operating mode: single port RAM 2048 x 16
|
||||
end else if (4'b0010 == mode) begin
|
||||
if (we_a) begin
|
||||
case (addr_a[10:10])
|
||||
1'b0 : ram_a[addr_a[0:9]][0:15] <= data_a[0:15];
|
||||
1'b1 : ram_a[addr_a[0:9]][16:31] <= data_a[0:15];
|
||||
endcase
|
||||
end else begin
|
||||
case (addr_a[10:10])
|
||||
1'b0 : q_a <= ram_a[addr_a[0:9]][0:15];
|
||||
1'b1 : q_a <= ram_a[addr_a[0:9]][16:31];
|
||||
endcase
|
||||
end
|
||||
// Operating mode: single port RAM 4096 x 8
|
||||
end else if (4'b0011 == mode) begin
|
||||
if (we_a) begin
|
||||
case (addr_a[10:11])
|
||||
2'b00 : ram_a[addr_a[0:9]][0:7] <= data_a[0:7];
|
||||
2'b01 : ram_a[addr_a[0:9]][8:15] <= data_a[0:7];
|
||||
2'b10 : ram_a[addr_a[0:9]][16:23] <= data_a[0:7];
|
||||
2'b11 : ram_a[addr_a[0:9]][24:31] <= data_a[0:7];
|
||||
endcase
|
||||
end else begin
|
||||
case (addr_a[10:11])
|
||||
2'b00 : q_a <= ram_a[addr_a[0:9]][0:7];
|
||||
2'b01 : q_a <= ram_a[addr_a[0:9]][8:15];
|
||||
2'b10 : q_a <= ram_a[addr_a[0:9]][16:23];
|
||||
2'b11 : q_a <= ram_a[addr_a[0:9]][24:31];
|
||||
endcase
|
||||
end
|
||||
// Operating mode: single port RAM 8192 x 4
|
||||
end else if (4'b0100 == mode) begin
|
||||
if (we_a) begin
|
||||
case (addr_a[10:12])
|
||||
3'b000 : ram_a[addr_a[0:9]][0:3] <= data_a[0:3];
|
||||
3'b001 : ram_a[addr_a[0:9]][4:7] <= data_a[0:3];
|
||||
3'b010 : ram_a[addr_a[0:9]][8:11] <= data_a[0:3];
|
||||
3'b011 : ram_a[addr_a[0:9]][12:15] <= data_a[0:3];
|
||||
3'b100 : ram_a[addr_a[0:9]][16:19] <= data_a[0:3];
|
||||
3'b101 : ram_a[addr_a[0:9]][20:23] <= data_a[0:3];
|
||||
3'b110 : ram_a[addr_a[0:9]][24:27] <= data_a[0:3];
|
||||
3'b111 : ram_a[addr_a[0:9]][28:31] <= data_a[0:3];
|
||||
endcase
|
||||
end else begin
|
||||
case (addr_a[10:12])
|
||||
3'b000 : q_a <= ram_a[addr_a[0:9]][0:3];
|
||||
3'b001 : q_a <= ram_a[addr_a[0:9]][4:7];
|
||||
3'b010 : q_a <= ram_a[addr_a[0:9]][8:11];
|
||||
3'b011 : q_a <= ram_a[addr_a[0:9]][12:15];
|
||||
3'b100 : q_a <= ram_a[addr_a[0:9]][16:19];
|
||||
3'b101 : q_a <= ram_a[addr_a[0:9]][20:23];
|
||||
3'b110 : q_a <= ram_a[addr_a[0:9]][24:27];
|
||||
3'b111 : q_a <= ram_a[addr_a[0:9]][28:31];
|
||||
endcase
|
||||
end
|
||||
// Operating mode: single port RAM 16384 x 2
|
||||
end else if (4'b0101 == mode) begin
|
||||
if (we_a) begin
|
||||
case (addr_a[10:13])
|
||||
4'b0000 : ram_a[addr_a[0:9]][0:1] <= data_a[0:1];
|
||||
4'b0001 : ram_a[addr_a[0:9]][2:3] <= data_a[0:1];
|
||||
4'b0010 : ram_a[addr_a[0:9]][4:5] <= data_a[0:1];
|
||||
4'b0011 : ram_a[addr_a[0:9]][6:7] <= data_a[0:1];
|
||||
4'b0100 : ram_a[addr_a[0:9]][8:9] <= data_a[0:1];
|
||||
4'b0101 : ram_a[addr_a[0:9]][10:11] <= data_a[0:1];
|
||||
4'b0110 : ram_a[addr_a[0:9]][12:13] <= data_a[0:1];
|
||||
4'b0111 : ram_a[addr_a[0:9]][14:15] <= data_a[0:1];
|
||||
4'b1000 : ram_a[addr_a[0:9]][16:17] <= data_a[0:1];
|
||||
4'b1001 : ram_a[addr_a[0:9]][18:19] <= data_a[0:1];
|
||||
4'b1010 : ram_a[addr_a[0:9]][20:21] <= data_a[0:1];
|
||||
4'b1011 : ram_a[addr_a[0:9]][22:23] <= data_a[0:1];
|
||||
4'b1100 : ram_a[addr_a[0:9]][24:25] <= data_a[0:1];
|
||||
4'b1101 : ram_a[addr_a[0:9]][26:27] <= data_a[0:1];
|
||||
4'b1110 : ram_a[addr_a[0:9]][28:29] <= data_a[0:1];
|
||||
4'b1111 : ram_a[addr_a[0:9]][30:31] <= data_a[0:1];
|
||||
endcase
|
||||
end else begin
|
||||
case (addr_a[10:13])
|
||||
4'b0000 : q_a <= ram_a[addr_a[0:9]][0:1];
|
||||
4'b0001 : q_a <= ram_a[addr_a[0:9]][2:3];
|
||||
4'b0010 : q_a <= ram_a[addr_a[0:9]][4:5];
|
||||
4'b0011 : q_a <= ram_a[addr_a[0:9]][6:7];
|
||||
4'b0100 : q_a <= ram_a[addr_a[0:9]][8:9];
|
||||
4'b0101 : q_a <= ram_a[addr_a[0:9]][10:11];
|
||||
4'b0110 : q_a <= ram_a[addr_a[0:9]][12:13];
|
||||
4'b0111 : q_a <= ram_a[addr_a[0:9]][14:15];
|
||||
4'b1000 : q_a <= ram_a[addr_a[0:9]][16:17];
|
||||
4'b1001 : q_a <= ram_a[addr_a[0:9]][18:19];
|
||||
4'b1010 : q_a <= ram_a[addr_a[0:9]][20:21];
|
||||
4'b1011 : q_a <= ram_a[addr_a[0:9]][22:23];
|
||||
4'b1100 : q_a <= ram_a[addr_a[0:9]][24:25];
|
||||
4'b1101 : q_a <= ram_a[addr_a[0:9]][26:27];
|
||||
4'b1110 : q_a <= ram_a[addr_a[0:9]][28:29];
|
||||
4'b1111 : q_a <= ram_a[addr_a[0:9]][30:31];
|
||||
endcase
|
||||
end
|
||||
// Operating mode: single port RAM 32768 x 1
|
||||
end else if (4'b0110 == mode) begin
|
||||
if (we_a) begin
|
||||
ram_a[addr_a[0:9]][addr_a[10:14]] = data_a[0:0];
|
||||
end else begin
|
||||
q_a <= ram_a[addr_a[0:9]][addr_a[10:14]];
|
||||
end
|
||||
// Operating mode: dual port RAM 1024 x 32
|
||||
end else if (4'b0111 == mode) begin
|
||||
if (we_a) begin
|
||||
ram_a[addr_a[0:9]] <= data_a;
|
||||
ram_b[addr_b[0:9]] <= data_b;
|
||||
q_a <= data_a;
|
||||
q_b <= data_b;
|
||||
end else begin
|
||||
q_a <= ram_a[addr_a[0:9]];
|
||||
q_b <= ram_b[addr_b[0:9]];
|
||||
end
|
||||
// Operating mode: dual port RAM 2048 x 16
|
||||
end else if (4'b1000 == mode) begin
|
||||
if (we_a) begin
|
||||
case (addr_a[10:10])
|
||||
1'b0 : ram_a[addr_a[0:9]][0:15] <= data_a;
|
||||
1'b1 : ram_a[addr_a[0:9]][16:31] <= data_a;
|
||||
endcase
|
||||
end else begin
|
||||
case (addr_a[10:10])
|
||||
1'b0 : q_a <= ram_a[addr_a[0:9]][0:15];
|
||||
1'b1 : q_a <= ram_a[addr_a[0:9]][16:31];
|
||||
endcase
|
||||
end
|
||||
|
||||
if (we_b) begin
|
||||
case (addr_b[10:10])
|
||||
1'b0 : ram_b[addr_b[0:9]][0:15] <= data_b;
|
||||
1'b1 : ram_b[addr_b[0:9]][16:31] <= data_b;
|
||||
endcase
|
||||
end else begin
|
||||
case (addr_b[10:10])
|
||||
1'b0 : q_b <= ram_b[addr_b[0:9]][0:15];
|
||||
1'b1 : q_b <= ram_b[addr_b[0:9]][16:31];
|
||||
endcase
|
||||
end
|
||||
// Operating mode: dual port RAM 4096 x 8
|
||||
end else if (4'b1001 == mode) begin
|
||||
if (we_a) begin
|
||||
case (addr_a[10:11])
|
||||
2'b00 : ram_a[addr_a[0:9]][0:7] <= data_a[0:7];
|
||||
2'b01 : ram_a[addr_a[0:9]][8:15] <= data_a[0:7];
|
||||
2'b10 : ram_a[addr_a[0:9]][16:23] <= data_a[0:7];
|
||||
2'b11 : ram_a[addr_a[0:9]][24:31] <= data_a[0:7];
|
||||
endcase
|
||||
end else begin
|
||||
case (addr_a[10:11])
|
||||
2'b00 : q_a <= ram_a[addr_a[0:9]][0:7];
|
||||
2'b01 : q_a <= ram_a[addr_a[0:9]][8:15];
|
||||
2'b10 : q_a <= ram_a[addr_a[0:9]][16:23];
|
||||
2'b11 : q_a <= ram_a[addr_a[0:9]][24:31];
|
||||
endcase
|
||||
end
|
||||
|
||||
if (we_b) begin
|
||||
case (addr_b[10:11])
|
||||
2'b00 : ram_b[addr_b[0:9]][0:7] <= data_b[0:7];
|
||||
2'b01 : ram_b[addr_b[0:9]][8:15] <= data_b[0:7];
|
||||
2'b10 : ram_b[addr_b[0:9]][16:23] <= data_b[0:7];
|
||||
2'b11 : ram_b[addr_b[0:9]][24:31] <= data_b[0:7];
|
||||
endcase
|
||||
end else begin
|
||||
case (addr_b[10:11])
|
||||
2'b00 : q_b <= ram_b[addr_b[0:9]][0:7];
|
||||
2'b01 : q_b <= ram_b[addr_b[0:9]][8:15];
|
||||
2'b10 : q_b <= ram_b[addr_b[0:9]][16:23];
|
||||
2'b11 : q_b <= ram_b[addr_b[0:9]][24:31];
|
||||
endcase
|
||||
end
|
||||
// Operating mode: dual port RAM 8192 x 4
|
||||
end else if (4'b1011 == mode) begin
|
||||
if (we_a) begin
|
||||
case (addr_a[10:12])
|
||||
3'b000 : ram_a[addr_a[0:9]][0:3] <= data_a[0:3];
|
||||
3'b001 : ram_a[addr_a[0:9]][4:7] <= data_a[0:3];
|
||||
3'b010 : ram_a[addr_a[0:9]][8:11] <= data_a[0:3];
|
||||
3'b011 : ram_a[addr_a[0:9]][12:15] <= data_a[0:3];
|
||||
3'b100 : ram_a[addr_a[0:9]][16:19] <= data_a[0:3];
|
||||
3'b101 : ram_a[addr_a[0:9]][20:23] <= data_a[0:3];
|
||||
3'b110 : ram_a[addr_a[0:9]][24:27] <= data_a[0:3];
|
||||
3'b111 : ram_a[addr_a[0:9]][28:31] <= data_a[0:3];
|
||||
endcase
|
||||
end else begin
|
||||
case (addr_a[10:12])
|
||||
3'b000 : q_a <= ram_a[addr_a[0:9]][0:3];
|
||||
3'b001 : q_a <= ram_a[addr_a[0:9]][4:7];
|
||||
3'b010 : q_a <= ram_a[addr_a[0:9]][8:11];
|
||||
3'b011 : q_a <= ram_a[addr_a[0:9]][12:15];
|
||||
3'b100 : q_a <= ram_a[addr_a[0:9]][16:19];
|
||||
3'b101 : q_a <= ram_a[addr_a[0:9]][20:23];
|
||||
3'b110 : q_a <= ram_a[addr_a[0:9]][24:27];
|
||||
3'b111 : q_a <= ram_a[addr_a[0:9]][28:31];
|
||||
endcase
|
||||
end
|
||||
if (we_b) begin
|
||||
case (addr_b[10:12])
|
||||
3'b000 : ram_b[addr_b[0:9]][0:3] <= data_b[0:3];
|
||||
3'b001 : ram_b[addr_b[0:9]][4:7] <= data_b[0:3];
|
||||
3'b010 : ram_b[addr_b[0:9]][8:11] <= data_b[0:3];
|
||||
3'b011 : ram_b[addr_b[0:9]][12:15] <= data_b[0:3];
|
||||
3'b100 : ram_b[addr_b[0:9]][16:19] <= data_b[0:3];
|
||||
3'b101 : ram_b[addr_b[0:9]][20:23] <= data_b[0:3];
|
||||
3'b110 : ram_b[addr_b[0:9]][24:27] <= data_b[0:3];
|
||||
3'b111 : ram_b[addr_b[0:9]][28:31] <= data_b[0:3];
|
||||
endcase
|
||||
end else begin
|
||||
case (addr_b[10:12])
|
||||
3'b000 : q_b <= ram_b[addr_b[0:9]][0:3];
|
||||
3'b001 : q_b <= ram_b[addr_b[0:9]][4:7];
|
||||
3'b010 : q_b <= ram_b[addr_b[0:9]][8:11];
|
||||
3'b011 : q_b <= ram_b[addr_b[0:9]][12:15];
|
||||
3'b100 : q_b <= ram_b[addr_b[0:9]][16:19];
|
||||
3'b101 : q_b <= ram_b[addr_b[0:9]][20:23];
|
||||
3'b110 : q_b <= ram_b[addr_b[0:9]][24:27];
|
||||
3'b111 : q_b <= ram_b[addr_b[0:9]][28:31];
|
||||
endcase
|
||||
end
|
||||
// Operating mode: dual port RAM 16384 x 2
|
||||
end else if (4'b1100 == mode) begin
|
||||
if (we_a) begin
|
||||
case (addr_a[10:13])
|
||||
4'b0000 : ram_a[addr_a[0:9]][0:1] <= data_a[0:1];
|
||||
4'b0001 : ram_a[addr_a[0:9]][2:3] <= data_a[0:1];
|
||||
4'b0010 : ram_a[addr_a[0:9]][4:5] <= data_a[0:1];
|
||||
4'b0011 : ram_a[addr_a[0:9]][6:7] <= data_a[0:1];
|
||||
4'b0100 : ram_a[addr_a[0:9]][8:9] <= data_a[0:1];
|
||||
4'b0101 : ram_a[addr_a[0:9]][10:11] <= data_a[0:1];
|
||||
4'b0110 : ram_a[addr_a[0:9]][12:13] <= data_a[0:1];
|
||||
4'b0111 : ram_a[addr_a[0:9]][14:15] <= data_a[0:1];
|
||||
4'b1000 : ram_a[addr_a[0:9]][16:17] <= data_a[0:1];
|
||||
4'b1001 : ram_a[addr_a[0:9]][18:19] <= data_a[0:1];
|
||||
4'b1010 : ram_a[addr_a[0:9]][20:21] <= data_a[0:1];
|
||||
4'b1011 : ram_a[addr_a[0:9]][22:23] <= data_a[0:1];
|
||||
4'b1100 : ram_a[addr_a[0:9]][24:25] <= data_a[0:1];
|
||||
4'b1101 : ram_a[addr_a[0:9]][26:27] <= data_a[0:1];
|
||||
4'b1110 : ram_a[addr_a[0:9]][28:29] <= data_a[0:1];
|
||||
4'b1111 : ram_a[addr_a[0:9]][30:31] <= data_a[0:1];
|
||||
endcase
|
||||
end else begin
|
||||
case (addr_a[10:13])
|
||||
4'b0000 : q_a <= ram_a[addr_a[0:9]][0:1];
|
||||
4'b0001 : q_a <= ram_a[addr_a[0:9]][2:3];
|
||||
4'b0010 : q_a <= ram_a[addr_a[0:9]][4:5];
|
||||
4'b0011 : q_a <= ram_a[addr_a[0:9]][6:7];
|
||||
4'b0100 : q_a <= ram_a[addr_a[0:9]][8:9];
|
||||
4'b0101 : q_a <= ram_a[addr_a[0:9]][10:11];
|
||||
4'b0110 : q_a <= ram_a[addr_a[0:9]][12:13];
|
||||
4'b0111 : q_a <= ram_a[addr_a[0:9]][14:15];
|
||||
4'b1000 : q_a <= ram_a[addr_a[0:9]][16:17];
|
||||
4'b1001 : q_a <= ram_a[addr_a[0:9]][18:19];
|
||||
4'b1010 : q_a <= ram_a[addr_a[0:9]][20:21];
|
||||
4'b1011 : q_a <= ram_a[addr_a[0:9]][22:23];
|
||||
4'b1100 : q_a <= ram_a[addr_a[0:9]][24:25];
|
||||
4'b1101 : q_a <= ram_a[addr_a[0:9]][26:27];
|
||||
4'b1110 : q_a <= ram_a[addr_a[0:9]][28:29];
|
||||
4'b1111 : q_a <= ram_a[addr_a[0:9]][30:31];
|
||||
endcase
|
||||
end
|
||||
if (we_b) begin
|
||||
case (addr_b[10:13])
|
||||
4'b0000 : ram_b[addr_b[0:9]][0:1] <= data_b[0:1];
|
||||
4'b0001 : ram_b[addr_b[0:9]][2:3] <= data_b[0:1];
|
||||
4'b0010 : ram_b[addr_b[0:9]][4:5] <= data_b[0:1];
|
||||
4'b0011 : ram_b[addr_b[0:9]][6:7] <= data_b[0:1];
|
||||
4'b0100 : ram_b[addr_b[0:9]][8:9] <= data_b[0:1];
|
||||
4'b0101 : ram_b[addr_b[0:9]][10:11] <= data_b[0:1];
|
||||
4'b0110 : ram_b[addr_b[0:9]][12:13] <= data_b[0:1];
|
||||
4'b0111 : ram_b[addr_b[0:9]][14:15] <= data_b[0:1];
|
||||
4'b1000 : ram_b[addr_b[0:9]][16:17] <= data_b[0:1];
|
||||
4'b1001 : ram_b[addr_b[0:9]][18:19] <= data_b[0:1];
|
||||
4'b1010 : ram_b[addr_b[0:9]][20:21] <= data_b[0:1];
|
||||
4'b1011 : ram_b[addr_b[0:9]][22:23] <= data_b[0:1];
|
||||
4'b1100 : ram_b[addr_b[0:9]][24:25] <= data_b[0:1];
|
||||
4'b1101 : ram_b[addr_b[0:9]][26:27] <= data_b[0:1];
|
||||
4'b1110 : ram_b[addr_b[0:9]][28:29] <= data_b[0:1];
|
||||
4'b1111 : ram_b[addr_b[0:9]][30:31] <= data_b[0:1];
|
||||
endcase
|
||||
end else begin
|
||||
case (addr_b[10:13])
|
||||
4'b0000 : q_b <= ram_b[addr_b[0:9]][0:1];
|
||||
4'b0001 : q_b <= ram_b[addr_b[0:9]][2:3];
|
||||
4'b0010 : q_b <= ram_b[addr_b[0:9]][4:5];
|
||||
4'b0011 : q_b <= ram_b[addr_b[0:9]][6:7];
|
||||
4'b0100 : q_b <= ram_b[addr_b[0:9]][8:9];
|
||||
4'b0101 : q_b <= ram_b[addr_b[0:9]][10:11];
|
||||
4'b0110 : q_b <= ram_b[addr_b[0:9]][12:13];
|
||||
4'b0111 : q_b <= ram_b[addr_b[0:9]][14:15];
|
||||
4'b1000 : q_b <= ram_b[addr_b[0:9]][16:17];
|
||||
4'b1001 : q_b <= ram_b[addr_b[0:9]][18:19];
|
||||
4'b1010 : q_b <= ram_b[addr_b[0:9]][20:21];
|
||||
4'b1011 : q_b <= ram_b[addr_b[0:9]][22:23];
|
||||
4'b1100 : q_b <= ram_b[addr_b[0:9]][24:25];
|
||||
4'b1101 : q_b <= ram_b[addr_b[0:9]][26:27];
|
||||
4'b1110 : q_b <= ram_b[addr_b[0:9]][28:29];
|
||||
4'b1111 : q_b <= ram_b[addr_b[0:9]][30:31];
|
||||
endcase
|
||||
end
|
||||
// Operating mode: dual port RAM 32768 x 1
|
||||
end else if (4'b1101 == mode) begin
|
||||
if (we_a) begin
|
||||
ram_a[addr_a[0:9]][addr_a[10:14]] = data_a[0:0];
|
||||
end else begin
|
||||
q_a <= ram_a[addr_a[0:9]][addr_a[10:14]];
|
||||
end
|
||||
if (we_b) begin
|
||||
ram_b[addr_b[0:9]][addr_b[10:14]] = data_b[0:0];
|
||||
end else begin
|
||||
q_b <= ram_b[addr_b[0:9]][addr_b[10:14]];
|
||||
end
|
||||
end
|
||||
end
|
||||
endmodule
|
Loading…
Reference in New Issue