summaryrefslogtreecommitdiff
path: root/tb/mem_interconnect.sv
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2023-09-30 17:44:26 -0600
committerAlejandro Soto <alejandro@34project.org>2023-10-01 01:04:19 -0600
commitcf6ab851183870bca61252a56b274342380d0960 (patch)
tree96c08231d60d300788462b17549d5120802e7f32 /tb/mem_interconnect.sv
parentd1b10aa380578b5af20081dd37f2d36ec111cbd2 (diff)
tb: implement quad-core SMP
Diffstat (limited to '')
-rw-r--r--tb/mem_interconnect.sv152
1 files changed, 152 insertions, 0 deletions
diff --git a/tb/mem_interconnect.sv b/tb/mem_interconnect.sv
new file mode 100644
index 0000000..e947568
--- /dev/null
+++ b/tb/mem_interconnect.sv
@@ -0,0 +1,152 @@
+module mem_interconnect
+(
+ input logic clk,
+ rst_n,
+
+ input logic avl_waitrequest,
+ input logic[127:0] avl_readdata,
+ output logic[31:0] avl_address,
+ output logic avl_read,
+ avl_write,
+ output logic[127:0] avl_writedata,
+ output logic[15:0] avl_byteenable,
+
+ input logic[31:0] mem_0_address,
+ mem_1_address,
+ mem_2_address,
+ mem_3_address,
+ input logic mem_0_read,
+ mem_1_read,
+ mem_2_read,
+ mem_3_read,
+ mem_0_write,
+ mem_1_write,
+ mem_2_write,
+ mem_3_write,
+ input logic[127:0] mem_0_writedata,
+ mem_1_writedata,
+ mem_2_writedata,
+ mem_3_writedata,
+ input logic[15:0] mem_0_byteenable,
+ mem_1_byteenable,
+ mem_2_byteenable,
+ mem_3_byteenable,
+ output logic mem_0_waitrequest,
+ mem_1_waitrequest,
+ mem_2_waitrequest,
+ mem_3_waitrequest,
+ output logic[127:0] mem_0_readdata,
+ mem_1_readdata,
+ mem_2_readdata,
+ mem_3_readdata
+);
+
+ logic last_hold;
+ logic[1:0] last_select, select;
+
+ assign mem_0_readdata = avl_readdata;
+ assign mem_1_readdata = avl_readdata;
+ assign mem_2_readdata = avl_readdata;
+ assign mem_3_readdata = avl_readdata;
+
+ always_comb begin
+ // Arbitraje round-robin
+ unique case (last_select)
+ 2'd0:
+ if (mem_1_read || mem_1_write)
+ select = 2'd1;
+ else if (mem_2_read || mem_2_write)
+ select = 2'd2;
+ else if (mem_3_read || mem_3_write)
+ select = 2'd3;
+ else
+ select = 2'd0;
+
+ 2'd1:
+ if (mem_2_read || mem_2_write)
+ select = 2'd2;
+ else if (mem_3_read || mem_3_write)
+ select = 2'd3;
+ else if (mem_0_read || mem_0_write)
+ select = 2'd0;
+ else
+ select = 2'd1;
+
+ 2'd2:
+ if (mem_3_read || mem_3_write)
+ select = 2'd3;
+ else if (mem_0_read || mem_0_write)
+ select = 2'd0;
+ else if (mem_1_read || mem_1_write)
+ select = 2'd1;
+ else
+ select = 2'd2;
+
+ 2'd3:
+ if (mem_0_read || mem_0_write)
+ select = 2'd0;
+ else if (mem_1_read || mem_1_write)
+ select = 2'd1;
+ else if (mem_2_read || mem_2_write)
+ select = 2'd2;
+ else
+ select = 2'd3;
+ endcase
+
+ if (last_hold)
+ select = last_select;
+
+ mem_0_waitrequest = 1;
+ mem_1_waitrequest = 1;
+ mem_2_waitrequest = 1;
+ mem_3_waitrequest = 1;
+
+ unique case (select)
+ 2'd0: begin
+ avl_read = mem_0_read;
+ avl_write = mem_0_write;
+ avl_address = mem_0_address;
+ avl_writedata = mem_0_writedata;
+ avl_byteenable = mem_0_byteenable;
+ mem_0_waitrequest = avl_waitrequest;
+ end
+
+ 2'd1: begin
+ avl_read = mem_1_read;
+ avl_write = mem_1_write;
+ avl_address = mem_1_address;
+ avl_writedata = mem_1_writedata;
+ avl_byteenable = mem_1_byteenable;
+ mem_1_waitrequest = avl_waitrequest;
+ end
+
+ 2'd2: begin
+ avl_read = mem_2_read;
+ avl_write = mem_2_write;
+ avl_address = mem_2_address;
+ avl_writedata = mem_2_writedata;
+ avl_byteenable = mem_2_byteenable;
+ mem_2_waitrequest = avl_waitrequest;
+ end
+
+ 2'd3: begin
+ avl_read = mem_3_read;
+ avl_write = mem_3_write;
+ avl_address = mem_3_address;
+ avl_writedata = mem_3_writedata;
+ avl_byteenable = mem_3_byteenable;
+ mem_3_waitrequest = avl_waitrequest;
+ end
+ endcase
+ end
+
+ always @(posedge clk or negedge rst_n)
+ if (!rst_n) begin
+ last_hold <= 1;
+ last_select <= 2'd0;
+ end else begin
+ last_hold <= (avl_read || avl_write) && avl_waitrequest;
+ last_select <= select;
+ end
+
+endmodule