diff --git a/scripts/vivado/system.v b/scripts/vivado/system.v index 86449a0..c4882a1 100644 --- a/scripts/vivado/system.v +++ b/scripts/vivado/system.v @@ -7,12 +7,15 @@ module system ( output reg [7:0] out_byte, output reg out_byte_en ); + // set this to 0 for better timing but less performance/MHz + parameter FAST_MEMORY = 1; + // 4096 32bit words = 16kB memory parameter MEM_SIZE = 4096; wire mem_valid; wire mem_instr; - wire mem_ready; + reg mem_ready; wire [31:0] mem_addr; wire [31:0] mem_wdata; wire [3:0] mem_wstrb; @@ -24,7 +27,7 @@ module system ( wire [31:0] mem_la_wdata; wire [3:0] mem_la_wstrb; - picorv32 uut ( + picorv32 picorv32_core ( .clk (clk ), .resetn (resetn ), .trap (trap ), @@ -45,21 +48,54 @@ module system ( reg [31:0] memory [0:MEM_SIZE-1]; initial $readmemh("firmware.hex", memory); - assign mem_ready = 1; + reg [31:0] m_read_data; + reg m_read_en; - always @(posedge clk) begin - out_byte_en <= 0; - mem_rdata <= memory[mem_la_addr >> 2]; - if (mem_la_write && (mem_la_addr >> 2) < MEM_SIZE) begin - if (mem_la_wstrb[0]) memory[mem_la_addr >> 2][ 7: 0] <= mem_la_wdata[ 7: 0]; - if (mem_la_wstrb[1]) memory[mem_la_addr >> 2][15: 8] <= mem_la_wdata[15: 8]; - if (mem_la_wstrb[2]) memory[mem_la_addr >> 2][23:16] <= mem_la_wdata[23:16]; - if (mem_la_wstrb[3]) memory[mem_la_addr >> 2][31:24] <= mem_la_wdata[31:24]; + generate if (FAST_MEMORY) begin + always @(posedge clk) begin + mem_ready <= 1; + out_byte_en <= 0; + mem_rdata <= memory[mem_la_addr >> 2]; + if (mem_la_write && (mem_la_addr >> 2) < MEM_SIZE) begin + if (mem_la_wstrb[0]) memory[mem_la_addr >> 2][ 7: 0] <= mem_la_wdata[ 7: 0]; + if (mem_la_wstrb[1]) memory[mem_la_addr >> 2][15: 8] <= mem_la_wdata[15: 8]; + if (mem_la_wstrb[2]) memory[mem_la_addr >> 2][23:16] <= mem_la_wdata[23:16]; + if (mem_la_wstrb[3]) memory[mem_la_addr >> 2][31:24] <= mem_la_wdata[31:24]; + end + else + if (mem_la_write && mem_la_addr == 32'h1000_0000) begin + out_byte_en <= 1; + out_byte <= mem_la_wdata; + end end - else - if (mem_la_write && mem_la_addr == 32'h1000_0000) begin - out_byte_en <= 1; - out_byte <= mem_la_wdata; + end else begin + always @(posedge clk) begin + m_read_en <= 0; + mem_ready <= mem_valid && !mem_ready && m_read_en; + + m_read_data <= memory[mem_addr >> 2]; + mem_rdata <= m_read_data; + + out_byte_en <= 0; + + (* parallel_case *) + case (1) + mem_valid && !mem_ready && !mem_wstrb && (mem_addr >> 2) < MEM_SIZE: begin + m_read_en <= 1; + end + mem_valid && !mem_ready && |mem_wstrb && (mem_addr >> 2) < MEM_SIZE: begin + if (mem_wstrb[0]) memory[mem_addr >> 2][ 7: 0] <= mem_wdata[ 7: 0]; + if (mem_wstrb[1]) memory[mem_addr >> 2][15: 8] <= mem_wdata[15: 8]; + if (mem_wstrb[2]) memory[mem_addr >> 2][23:16] <= mem_wdata[23:16]; + if (mem_wstrb[3]) memory[mem_addr >> 2][31:24] <= mem_wdata[31:24]; + mem_ready <= 1; + end + mem_valid && !mem_ready && |mem_wstrb && mem_addr == 32'h1000_0000: begin + out_byte_en <= 1; + out_byte <= mem_wdata; + mem_ready <= 1; + end + endcase end - end + end endgenerate endmodule diff --git a/scripts/vivado/system_tb.v b/scripts/vivado/system_tb.v index f0676ca..a66d612 100644 --- a/scripts/vivado/system_tb.v +++ b/scripts/vivado/system_tb.v @@ -6,6 +6,10 @@ module system_tb; reg resetn = 0; initial begin + if ($test$plusargs("vcd")) begin + $dumpfile("system.vcd"); + $dumpvars(0, system_tb); + end repeat (100) @(posedge clk); resetn <= 1; end