From 4716d75bf5fa0b7ea12bcb7906b09add1eae7bdd Mon Sep 17 00:00:00 2001 From: Gyorgy Szombathelyi Date: Mon, 21 Oct 2019 12:08:30 +0200 Subject: [PATCH 1/4] Archie: update SDRAM testbench --- cores/archie/bench/sdram/sdram.cpp | 61 ++++++++++++++++++---- cores/archie/bench/support/mt48lc16m16a2.v | 12 ++++- 2 files changed, 61 insertions(+), 12 deletions(-) diff --git a/cores/archie/bench/sdram/sdram.cpp b/cores/archie/bench/sdram/sdram.cpp index 5e4bb65..745e538 100644 --- a/cores/archie/bench/sdram/sdram.cpp +++ b/cores/archie/bench/sdram/sdram.cpp @@ -5,6 +5,7 @@ #include "edge.h" #include +#include #include @@ -130,10 +131,40 @@ int wb_read32(int address) uut->wb_we = 0; uut->wb_cti = 0; - return uut->wb_dat_o; } +int wb_write32(int address, int data) +{ + wait_ready(); + wait_nack(); + + while (!Verilated::gotFinish()) + { + if (wb_clk.PosEdge()) + { + uut->wb_adr = address; + uut->wb_dat_i = data; + uut->wb_sel = 0xF; + uut->wb_cyc = 1; + uut->wb_stb = 1; + uut->wb_we = 1; + uut->wb_cti = 0; + break; + } + + tick(); + } + + wait_ack(); + + uut->wb_cyc = 0; + uut->wb_stb = 0; + uut->wb_we = 0; + uut->wb_cti = 0; + + return uut->wb_dat_o; +} void wb_read32x4(int address, int result[4]) { @@ -218,19 +249,29 @@ int main(int argc, char** argv) tick(); tick(); wait_ready(); - - std::cout << std::hex << wb_read32(0) << std::dec << std::endl; - std::cout << std::hex << wb_read32(4) << std::dec << std::endl; - std::cout << std::hex << wb_read32(8) << std::dec << std::endl; - std::cout << std::hex << wb_read32(12) << std::dec << std::endl; + std::cout << "32 bit reads" << std::endl; + std::cout << std::setw(8) << std::setfill('0') << std::hex << wb_read32(0) << std::dec << std::endl; + std::cout << std::setw(8) << std::setfill('0') << std::hex << wb_read32(4) << std::dec << std::endl; + std::cout << std::setw(8) << std::setfill('0') << std::hex << wb_read32(8) << std::dec << std::endl; + std::cout << std::setw(8) << std::setfill('0') << std::hex << wb_read32(12) << std::dec << std::endl; int result[4] = {0,0}; wb_read32x4(0, result); + std::cout << "128 bit read" << std::endl; + std::cout << std::setw(8) << std::setfill('0') << std::hex << result[0] << std::dec << std::endl; + std::cout << std::setw(8) << std::setfill('0') << std::hex << result[1] << std::dec << std::endl; + std::cout << std::setw(8) << std::setfill('0') << std::hex << result[2] << std::dec << std::endl; + std::cout << std::setw(8) << std::setfill('0') << std::hex << result[3] << std::dec << std::endl; - std::cout << std::hex << result[0] << std::dec << std::endl; - std::cout << std::hex << result[1] << std::dec << std::endl; - std::cout << std::hex << result[2] << std::dec << std::endl; - std::cout << std::hex << result[3] << std::dec << std::endl; + std::cout << "32 bit write/read back" << std::endl; + wb_write32(0xaaaa, 0x01020304); + std::cout << std::setw(8) << std::setfill('0') << std::hex << wb_read32(0xaaaa) << std::dec << std::endl; + wb_write32(0xbbbb, 0x05060708); + std::cout << std::setw(8) << std::setfill('0') << std::hex << wb_read32(0xbbbb) << std::dec << std::endl; + + + std::cout << std::setw(8) << std::setfill('0') << std::hex << wb_read32(0xaaaa) << std::dec << std::endl; + std::cout << std::setw(8) << std::setfill('0') << std::hex << wb_read32(0xbbbb) << std::dec << std::endl; for (int i=0; i < 64; i++) diff --git a/cores/archie/bench/support/mt48lc16m16a2.v b/cores/archie/bench/support/mt48lc16m16a2.v index 3e2efe5..8ee7990 100644 --- a/cores/archie/bench/support/mt48lc16m16a2.v +++ b/cores/archie/bench/support/mt48lc16m16a2.v @@ -201,7 +201,9 @@ module mt48lc16m16a2 (Dq, Addr, Ba, Clk, Cke, Cs_n, Ras_n, Cas_n, We_n, Dqm); initial begin +`ifndef VERILATOR Dq_reg = {data_bits{1'bz}}; +`endif Data_in_enable = 0; Data_out_enable = 0; Act_b0 = 1; Act_b1 = 1; Act_b2 = 1; Act_b3 = 1; Pc_b0 = 0; Pc_b1 = 0; Pc_b2 = 0; Pc_b3 = 0; @@ -1028,7 +1030,7 @@ end 2'b10 : Dq_dqm = Bank2[{Row, Col}]; 2'b11 : Dq_dqm = Bank3[{Row, Col}]; endcase - +`ifndef VERILATOR // Dqm operation if (Dqm_reg0 [0] == 1'b1) begin Dq_dqm [ 7 : 0] = 8'bz; @@ -1036,15 +1038,21 @@ end if (Dqm_reg0 [1] == 1'b1) begin Dq_dqm [15 : 8] = 8'bz; end - +`endif // Display debug message if (Dqm_reg0 !== 2'b11) begin +`ifdef VERILATOR + Dq_reg <= Dq_dqm; +`else Dq_reg = #tAC Dq_dqm; +`endif if (Debug) begin $display("%m : at time %t READ : Bank = %h Row = %h, Col = %h, Data = %h", $time, Bank, Row, Col, Dq_reg); end end else begin +`ifndef VERILATOR Dq_reg = #tHZ {data_bits{1'bz}}; +`endif if (Debug) begin $display("%m : at time %t READ : Bank = %h Row = %h, Col = %h, Data = Hi-Z due to DQM", $time, Bank, Row, Col); end From 1b4884aaa6b4d771b755ac3168ed54e1474b0852 Mon Sep 17 00:00:00 2001 From: Gyorgy Szombathelyi Date: Mon, 21 Oct 2019 12:09:42 +0200 Subject: [PATCH 2/4] Archie: fix possible bug when wb_we change too soon after wb_ack --- cores/archie/rtl/sdram/sdram_top.v | 34 +++++++++++++++--------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/cores/archie/rtl/sdram/sdram_top.v b/cores/archie/rtl/sdram/sdram_top.v index 3a924cd..d9cc2c7 100644 --- a/cores/archie/rtl/sdram/sdram_top.v +++ b/cores/archie/rtl/sdram/sdram_top.v @@ -113,7 +113,7 @@ localparam REFRESH_PERIOD = (RAM_CLK / (16 * 8192)) - CYCLE_END; `ifdef VERILATOR reg [15:0] sd_q; -assign sd_dq = (sd_writing && (sd_cycle == CYCLE_CAS1 || sd_cycle == CYCLE_CAS2)) ? sd_q : 16'bZZZZZZZZZZZZZZZZ; +assign sd_dq = (sd_we && (sd_cycle == CYCLE_CAS1 || sd_cycle == CYCLE_CAS2)) ? sd_q : 16'bZZZZZZZZZZZZZZZZ; `endif always @(posedge sd_clk) begin @@ -162,7 +162,6 @@ always @(posedge sd_clk) begin // bring the wishbone bus signal into the ram clock domain. - sd_we <= wb_we; if (sd_req) begin sd_stb <= wb_stb; sd_cyc <= wb_cyc; @@ -195,6 +194,7 @@ always @(posedge sd_clk) begin sd_auto_refresh <= 1'b0; sd_cycle <= 5'd0; end + default: ; endcase end else if (sd_cyc | (sd_cycle != 0) | (sd_cycle == 0 && sd_req)) begin @@ -203,6 +203,7 @@ always @(posedge sd_clk) begin sd_cycle <= sd_cycle + 1'd1; case (sd_cycle) CYCLE_PRECHARGE: begin + sd_we <= wb_we; if (~sd_bank_active[sd_bank]) sd_cycle <= CYCLE_RAS_START; else if (sd_active_row[sd_bank] == sd_row) @@ -228,9 +229,9 @@ always @(posedge sd_clk) begin sd_addr <= { 4'b0000, wb_adr[23], wb_adr[8:2], 1'b0 }; // no auto precharge sd_ba <= sd_bank; - if (sd_reading) begin + if (~sd_we) begin sd_cmd <= CMD_READ; - end else if (sd_writing) begin + end else begin sd_cmd <= CMD_WRITE; sd_dqm <= ~wb_sel[1:0]; `ifdef VERILATOR @@ -244,10 +245,10 @@ always @(posedge sd_clk) begin CYCLE_CAS1: begin // now we access the second part of the 32 bit location. sd_addr <= { 4'b0000, wb_adr[23], wb_adr[8:2], 1'b1 }; // no auto precharge - if (sd_reading) sd_dqm <= ~wb_sel[1:0]; - if (sd_reading & burst_mode & can_burst) sd_burst <= 1'b1; + if (~sd_we) sd_dqm <= ~wb_sel[1:0]; + if (~sd_we & burst_mode & can_burst) sd_burst <= 1'b1; - if (sd_writing) begin + if (sd_we) begin sd_cmd <= CMD_WRITE; sd_dqm <= ~wb_sel[3:2]; sd_done <= ~sd_done; @@ -259,18 +260,17 @@ always @(posedge sd_clk) begin end end - CYCLE_CAS2: if (sd_reading) sd_dqm <= ~wb_sel[3:2]; + CYCLE_CAS2: if (~sd_we) sd_dqm <= ~wb_sel[3:2]; CYCLE_READ0: begin - if (sd_reading) begin - sd_dat[0][15:0] <= sd_dq; - sd_word <= 2'b01; - end else begin - if (sd_writing) sd_cycle <= CYCLE_END; - end + if (~sd_we) begin + sd_dat[0][15:0] <= sd_dq; + sd_word <= 3'b001; + end else + sd_cycle <= CYCLE_END; end - CYCLE_READ1: if (sd_reading) sd_done <= ~sd_done; + CYCLE_READ1: if (~sd_we) sd_done <= ~sd_done; CYCLE_END: begin sd_burst <= 1'b0; @@ -278,6 +278,8 @@ always @(posedge sd_clk) begin sd_stb <= 1'b0; sd_cycle <= 5'd0; end + + default: ; endcase end else begin sd_cycle <= 5'd0; @@ -326,8 +328,6 @@ end wire burst_mode = wb_cti == 3'b010; wire can_burst = wb_adr[2] === 1'b0; -wire sd_reading = sd_stb & sd_cyc & ~sd_we; -wire sd_writing = sd_stb & sd_cyc & sd_we; // drive control signals according to current command assign sd_cs_n = sd_cmd[3]; From 40e8f7e8443ad0a4562ffc16b00ff22ee5bddbf6 Mon Sep 17 00:00:00 2001 From: Gyorgy Szombathelyi Date: Mon, 21 Oct 2019 17:37:06 +0200 Subject: [PATCH 3/4] Archie: re-use the already fetched burst As a primitive 128 bit cache --- cores/archie/bench/sdram/sdram.cpp | 27 ++++++++++++-- cores/archie/rtl/sdram/sdram_top.v | 60 ++++++++++++++++-------------- 2 files changed, 57 insertions(+), 30 deletions(-) diff --git a/cores/archie/bench/sdram/sdram.cpp b/cores/archie/bench/sdram/sdram.cpp index 745e538..2662b93 100644 --- a/cores/archie/bench/sdram/sdram.cpp +++ b/cores/archie/bench/sdram/sdram.cpp @@ -266,12 +266,33 @@ int main(int argc, char** argv) std::cout << "32 bit write/read back" << std::endl; wb_write32(0xaaaa, 0x01020304); std::cout << std::setw(8) << std::setfill('0') << std::hex << wb_read32(0xaaaa) << std::dec << std::endl; - wb_write32(0xbbbb, 0x05060708); - std::cout << std::setw(8) << std::setfill('0') << std::hex << wb_read32(0xbbbb) << std::dec << std::endl; + wb_write32(0xbbbc, 0x05060708); + std::cout << std::setw(8) << std::setfill('0') << std::hex << wb_read32(0xbbbc) << std::dec << std::endl; + std::cout << std::setw(8) << std::setfill('0') << std::hex << wb_read32(0xaaaa) << std::dec << std::endl; + std::cout << std::setw(8) << std::setfill('0') << std::hex << wb_read32(0xbbbc) << std::dec << std::endl; std::cout << std::setw(8) << std::setfill('0') << std::hex << wb_read32(0xaaaa) << std::dec << std::endl; - std::cout << std::setw(8) << std::setfill('0') << std::hex << wb_read32(0xbbbb) << std::dec << std::endl; + std::cout << std::setw(8) << std::setfill('0') << std::hex << wb_read32(0xbbbc) << std::dec << std::endl; + + std::cout << "32 bit write/read back from cache" << std::endl; + wb_write32(0xccc0, 0x01020304); + wb_write32(0xccc4, 0x05060708); + wb_write32(0xccc8, 0x090a0b0c); + wb_write32(0xcccc, 0x0d0e0f01); + + std::cout << "32 bit read back" << std::endl; + std::cout << std::setw(8) << std::setfill('0') << std::hex << wb_read32(0xccc8) << std::dec << std::endl; + std::cout << std::setw(8) << std::setfill('0') << std::hex << wb_read32(0xccc4) << std::dec << std::endl; + std::cout << std::setw(8) << std::setfill('0') << std::hex << wb_read32(0xccc0) << std::dec << std::endl; + std::cout << std::setw(8) << std::setfill('0') << std::hex << wb_read32(0xcccc) << std::dec << std::endl; + + std::cout << "128 bit read back" << std::endl; + wb_read32x4(0xccc0, result); + std::cout << std::setw(8) << std::setfill('0') << std::hex << result[0] << std::dec << std::endl; + std::cout << std::setw(8) << std::setfill('0') << std::hex << result[1] << std::dec << std::endl; + std::cout << std::setw(8) << std::setfill('0') << std::hex << result[2] << std::dec << std::endl; + std::cout << std::setw(8) << std::setfill('0') << std::hex << result[3] << std::dec << std::endl; for (int i=0; i < 64; i++) diff --git a/cores/archie/rtl/sdram/sdram_top.v b/cores/archie/rtl/sdram/sdram_top.v index d9cc2c7..bf35635 100644 --- a/cores/archie/rtl/sdram/sdram_top.v +++ b/cores/archie/rtl/sdram/sdram_top.v @@ -83,6 +83,7 @@ reg [11:0] sd_active_row[3:0]; reg [3:0] sd_bank_active; wire [1:0] sd_bank = wb_adr[22:21]; wire [11:0] sd_row = wb_adr[20:9]; +reg [23:0] sd_last_adr; initial begin t = 4'd0; @@ -128,8 +129,10 @@ always @(posedge sd_clk) begin reset <= 5'h1f; sd_addr <= 13'd0; sd_ready <= 0; + sd_last_adr <= 24'hffffff; end else begin if (!sd_ready) begin + sd_last_adr <= 24'hffffff; sd_word <= 0; t <= t + 1'd1; @@ -204,14 +207,24 @@ always @(posedge sd_clk) begin case (sd_cycle) CYCLE_PRECHARGE: begin sd_we <= wb_we; - if (~sd_bank_active[sd_bank]) - sd_cycle <= CYCLE_RAS_START; - else if (sd_active_row[sd_bank] == sd_row) - sd_cycle <= CYCLE_CAS0; - else begin - sd_cmd <= CMD_PRECHARGE; - sd_addr[10] <= 0; - sd_ba <= sd_bank; + word_index <= 2'b00; + if (~wb_we && sd_last_adr[23:4] == wb_adr[23:4]) begin + // this word is already in sd_dat, but where? + word_index <= wb_adr[3:2] - sd_last_adr[3:2]; + sd_done <= ~sd_done; + sd_cycle <= CYCLE_READ4; // allow time to de-assert wb_cyc + end else begin + sd_last_adr <= wb_we ? 24'hffffff : wb_adr; + + if (~sd_bank_active[sd_bank]) + sd_cycle <= CYCLE_RAS_START; + else if (sd_active_row[sd_bank] == sd_row) + sd_cycle <= CYCLE_CAS0; + else begin + sd_cmd <= CMD_PRECHARGE; + sd_addr[10] <= 0; + sd_ba <= sd_bank; + end end end @@ -291,39 +304,32 @@ end reg wb_burst; reg [1:0] wb_word; +reg [1:0] word_index; + always @(posedge wb_clk) begin reg sd_doneD; - + sd_doneD <= sd_done; wb_ack <= (sd_done ^ sd_doneD) & ~wb_ack; - + if (wb_stb & wb_cyc) begin - + if ((sd_done ^ sd_doneD) & ~wb_ack) begin - - wb_dat_o <= sd_dat[0]; + wb_dat_o <= sd_dat[word_index]; wb_burst <= burst_mode; - wb_word <= 2'b01; - + wb_word <= word_index + 1'd1; end - + if (wb_ack & wb_burst) begin - wb_ack <= 1'b1; - wb_burst <= ~&wb_word; + wb_burst <= (wb_word + 1'd1) != word_index; wb_word <= wb_word + 1'd1; wb_dat_o <= sd_dat[wb_word]; - end - - - end else begin - - wb_burst <= 1'b0; - - end - + end else begin + wb_burst <= 1'b0; + end end wire burst_mode = wb_cti == 3'b010; From 434ea845de58f733318ca05512fdf409615dc623 Mon Sep 17 00:00:00 2001 From: Gyorgy Szombathelyi Date: Mon, 21 Oct 2019 19:52:32 +0200 Subject: [PATCH 4/4] Archie: transfer hsync to cpuclk domain for using in MEMC --- cores/archie/rtl/archimedes_top.v | 8 +++++--- cores/archie/rtl/vidc.v | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/cores/archie/rtl/archimedes_top.v b/cores/archie/rtl/archimedes_top.v index f2173ff..bf02d73 100644 --- a/cores/archie/rtl/archimedes_top.v +++ b/cores/archie/rtl/archimedes_top.v @@ -125,6 +125,7 @@ module archimedes_top( (*KEEP="TRUE"*)wire rom_low_cs/* synthesis keep */ ; wire [5:0] ioc_cin, ioc_cout; +wire hsync_cpu; a23_core ARM( @@ -182,7 +183,7 @@ memc MEMC( .mem_cti_o ( MEM_CTI_O ), // vidc interface - .hsync ( HSYNC ), + .hsync ( hsync_cpu ), .flybk ( vid_flybk ), .vidrq ( vid_req ), .vidak ( vid_ack ), @@ -211,7 +212,8 @@ vidc VIDC( .cpu_dat ( cpu_dat_o ), // memc - .flybk ( vid_flybk ), + .flybk ( vid_flybk ), + .hsync_cpu ( hsync_cpu ), .vidak ( vid_ack ), .vidrq ( vid_req ), .sndak ( snd_ack ), @@ -303,7 +305,7 @@ podules PODULES( .wb_dat_o ( pod_dat_o ), .wb_dat_i ( cpu_dat_o[15:0] ), - .wb_adr ( cpu_address[15:2] ), + .wb_adr ( cpu_address[15:2] ) ); wire [7:0] floppy_dat_o; diff --git a/cores/archie/rtl/vidc.v b/cores/archie/rtl/vidc.v index e513185..fb129d6 100644 --- a/cores/archie/rtl/vidc.v +++ b/cores/archie/rtl/vidc.v @@ -46,7 +46,8 @@ module vidc( output sndrq, output flybk, - + output reg hsync_cpu, + // video outputs output hsync, output vsync, @@ -102,7 +103,6 @@ wire snd_load; // internal data request lines wire currq_int; wire vidrq_int; -reg hsync_cpu; reg cepix;