From b6bd487b7e9d36e4aa165abcba36650f9ddc08dd Mon Sep 17 00:00:00 2001 From: slederer Date: Sun, 16 Mar 2025 00:10:53 +0100 Subject: [PATCH] tridoracpu: first attempt at instruction cache --- .gitignore | 1 + tridoracpu/tridoracpu.srcs/dram_bridge.v | 45 ++++++++++++------- tridoracpu/tridoracpu.srcs/stackcpu.v | 12 ++--- tridoracpu/tridoracpu.srcs/top.v | 22 +++------ tridoracpu/tridoracpu.xpr | 57 ++++++++++++++---------- 5 files changed, 75 insertions(+), 62 deletions(-) diff --git a/.gitignore b/.gitignore index 765db6a..d4ecaa9 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,7 @@ pcomp/sdis tridoraemu/tridoraemu **/tridoracpu.cache/ **/tridoracpu.hw/ +**/tridoracpu.gen/ **/tridoracpu.ip_user_files/ **/tridoracpu.runs/ *.log diff --git a/tridoracpu/tridoracpu.srcs/dram_bridge.v b/tridoracpu/tridoracpu.srcs/dram_bridge.v index 102a8cf..1b60fd0 100644 --- a/tridoracpu/tridoracpu.srcs/dram_bridge.v +++ b/tridoracpu/tridoracpu.srcs/dram_bridge.v @@ -8,6 +8,7 @@ module dram_bridge #(ADDR_WIDTH = 32, WIDTH = 32) input wire [WIDTH-1:0] mem_write_data, input wire mem_read_enable, input wire mem_write_enable, + input wire mem_read_ins, output wire mem_wait, input wire rst_n, @@ -105,31 +106,35 @@ module dram_bridge #(ADDR_WIDTH = 32, WIDTH = 32) .sys_rst (rst_n) ); -// reg [DRAM_DATA_WIDTH-1:0] read_cache; -// reg [ADDR_WIDTH-1:0] cached_addr; -// wire cache_hit = cached_addr == mem_addr; -// wire [DRAM_DATA_WIDTH-1:0] read_data_wrapper = cache_hit ? read_cache : app_rd_data; + reg [DRAM_DATA_WIDTH-1:0] ins_cache; + reg [DRAM_ADDR_WIDTH-1:4] cached_addr; + wire cache_hit = mem_read_ins && (cached_addr == mem_addr[DRAM_ADDR_WIDTH:4]); + wire [DRAM_DATA_WIDTH-1:0] read_data_wrapper = cache_hit ? ins_cache : app_rd_data; reg [WIDTH-1:0] read_buf; reg read_inprogress = 0; + wire dram_read_enable = mem_read_enable && !cache_hit; assign app_rd_data_end = 1'b1; - //assign app_wdf_mask = 16'b1111111111111100; // addresses on the memory interface are aligned to 16 bytes // and 28 bits wide (=256MB) assign app_addr = { mem_addr[DRAM_ADDR_WIDTH:4], 4'b0000 }; - //assign app_addr = { 28'b0 }; // select a word from the 128 bits transferred by the dram controller // according to the lower bits of the address (ignoring bits 1:0) wire [WIDTH-1:0] read_word; wire [1:0] word_sel = mem_addr[3:2]; - assign read_word = word_sel == 3'b11 ? app_rd_data[31:0] : - word_sel == 3'b10 ? app_rd_data[63:32] : - word_sel == 3'b01 ? app_rd_data[95:64] : - app_rd_data[127:96]; +// assign read_word = word_sel == 3'b11 ? app_rd_data[31:0] : +// word_sel == 3'b10 ? app_rd_data[63:32] : +// word_sel == 3'b01 ? app_rd_data[95:64] : +// app_rd_data[127:96]; + + assign read_word = word_sel == 3'b11 ? read_data_wrapper[31:0] : + word_sel == 3'b10 ? read_data_wrapper[63:32] : + word_sel == 3'b01 ? read_data_wrapper[95:64] : + read_data_wrapper[127:96]; assign mem_read_data = app_rd_data_valid ? read_word : read_buf; @@ -145,21 +150,31 @@ module dram_bridge #(ADDR_WIDTH = 32, WIDTH = 32) assign app_wdf_end = mem_write_enable & write_ready; assign app_wdf_data = { {4{mem_write_data}} }; - assign mem_wait = (mem_read_enable & ~read_inprogress) | + assign mem_wait = (dram_read_enable & ~read_inprogress) | (mem_write_enable & (~app_wdf_rdy | ~app_rdy)) | (read_inprogress & ~app_rd_data_valid); - assign app_en = (mem_read_enable & ~read_inprogress) | + assign app_en = (dram_read_enable & ~read_inprogress) | (mem_write_enable & write_ready); - assign app_cmd = mem_read_enable ? CMD_READ : CMD_WRITE; + assign app_cmd = dram_read_enable ? CMD_READ : CMD_WRITE; + always @(posedge dram_front_clk) begin - if(mem_read_enable & ~read_inprogress & app_rdy) + if(mem_read_enable && mem_read_ins && ~cache_hit && app_rd_data_valid) + begin + ins_cache <= mem_read_data; + cached_addr <= mem_addr[DRAM_ADDR_WIDTH:4]; + end + end + + always @(posedge dram_front_clk) + begin + if(dram_read_enable & ~read_inprogress & app_rdy) read_inprogress <= 1; if(read_inprogress & app_rd_data_valid) read_inprogress <= 0; - if(mem_read_enable & app_rd_data_valid) + if(dram_read_enable & app_rd_data_valid) read_buf <= mem_read_data; end endmodule diff --git a/tridoracpu/tridoracpu.srcs/stackcpu.v b/tridoracpu/tridoracpu.srcs/stackcpu.v index c65ae4e..33b58ec 100644 --- a/tridoracpu/tridoracpu.srcs/stackcpu.v +++ b/tridoracpu/tridoracpu.srcs/stackcpu.v @@ -11,20 +11,14 @@ module stackcpu #(parameter ADDR_WIDTH = 32, WIDTH = 32, output reg [ADDR_WIDTH-1:0] addr, input wire [WIDTH-1:0] data_in, output wire read_enable, + output wire read_ins, output wire [WIDTH-1:0] data_out, output wire write_enable, input wire mem_wait, output wire led1, output wire led2, - output wire led3, - - output wire [WIDTH-1:0] debug_out1, - output wire [WIDTH-1:0] debug_out2, - output wire [WIDTH-1:0] debug_out3, - output wire [WIDTH-1:0] debug_out4, - output wire [WIDTH-1:0] debug_out5, - output wire [WIDTH-1:0] debug_out6 + output wire led3 ); localparam EVAL_STACK_INDEX_WIDTH = 6; @@ -182,6 +176,8 @@ module stackcpu #(parameter ADDR_WIDTH = 32, WIDTH = 32, assign mem_read_enable = (seq_state == FETCH) || (seq_state == EXEC && mem_read); assign mem_write_enable = (seq_state == MEM && mem_write); + assign read_ins = (seq_state == FETCH) || (seq_state == DECODE); + initial begin PC <= 0; nPC <= 0; seq_state <= MEM; diff --git a/tridoracpu/tridoracpu.srcs/top.v b/tridoracpu/tridoracpu.srcs/top.v index 2af2d10..0496573 100644 --- a/tridoracpu/tridoracpu.srcs/top.v +++ b/tridoracpu/tridoracpu.srcs/top.v @@ -72,6 +72,7 @@ module top( wire [WIDTH-1:0] mem_read_data; wire [WIDTH-1:0] mem_write_data; (* KEEP *) wire mem_wait; + assign led0 = mem_wait; (* KEEP *) wire mem_read_enable; (* KEEP *) wire mem_write_enable; @@ -81,14 +82,6 @@ module top( wire irq; - // assign led0 = mem_wait; - - wire [WIDTH-1:0] debug_data1, debug_data2, - debug_data3, debug_data4, - debug_data5, debug_data6; - - assign led0 = debug_data6[0]; - wire cpuclk, cpuclk_locked; wire dram_refclk200; wire pixclk; @@ -98,9 +91,11 @@ module top( wire [ADDR_WIDTH-1:0] dram_addr; wire [WIDTH-1:0] dram_read_data, dram_write_data; wire dram_read_enable, dram_write_enable, dram_wait; + wire dram_read_ins; dram_bridge dram_bridge0 (dram_addr, - dram_read_data, dram_write_data, dram_read_enable, dram_write_enable, dram_wait, + dram_read_data, dram_write_data, dram_read_enable, dram_write_enable, + dram_read_ins, dram_wait, rst, cpuclk, dram_refclk200, ddr3_dq, ddr3_dqs_n, ddr3_dqs_p, ddr3_addr, ddr3_ba, ddr3_ras_n, ddr3_cas_n, ddr3_we_n, @@ -255,15 +250,10 @@ module top( stackcpu cpu0(.clk(`clock), .rst(rst), .irq(irq), .addr(mem_addr), .data_in(mem_read_data), .read_enable(mem_read_enable), + .read_ins(dram_read_ins), .data_out(mem_write_data), .write_enable(mem_write_enable), .mem_wait(mem_wait), - .led1(led1), .led2(led2), .led3(led3), - .debug_out1(debug_data1), - .debug_out2(debug_data2), - .debug_out3(debug_data3), - .debug_out4(debug_data4), - .debug_out5(debug_data5), - .debug_out6(debug_data6)); + .led1(led1), .led2(led2), .led3(led3)); // Interrupt Controller irqctrl irqctrl0(`clock, irq_in, irqc_cs, mem_write_enable, diff --git a/tridoracpu/tridoracpu.xpr b/tridoracpu/tridoracpu.xpr index 721335b..017971d 100644 --- a/tridoracpu/tridoracpu.xpr +++ b/tridoracpu/tridoracpu.xpr @@ -1,10 +1,10 @@ - + - + - + - + @@ -210,7 +210,7 @@ - + @@ -223,7 +223,7 @@ - + @@ -246,16 +246,19 @@ - + - + @@ -282,9 +285,12 @@ - + @@ -305,10 +311,13 @@ - + @@ -352,7 +361,9 @@ - + + Vivado Synthesis Defaults + @@ -388,7 +399,9 @@ - + + Default settings for Implementation. + @@ -404,9 +417,7 @@ - - - +