From eaba318d41dfd80aff73f46a38dc6a35a2e1ecfd Mon Sep 17 00:00:00 2001 From: kitune-san <19359213+kitune-san@users.noreply.github.com> Date: Mon, 15 Aug 2022 13:07:19 +0900 Subject: [PATCH] Improved access speed to SDRAM. --- PCXT.sdc | 2 +- rtl/KFPC-XT/HDL/Chipset.sv | 6 +- rtl/KFPC-XT/HDL/KFSDRAM/HDL/KFSDRAM.sv | 99 ++++++-------- rtl/KFPC-XT/HDL/RAM.sv | 171 ++++++++----------------- 4 files changed, 95 insertions(+), 183 deletions(-) diff --git a/PCXT.sdc b/PCXT.sdc index de0a901..9769662 100644 --- a/PCXT.sdc +++ b/PCXT.sdc @@ -47,7 +47,7 @@ set_max_delay -to [get_registers {emu:emu|CHIPSET:u_CHIPSET|PERIPHERALS:u_PERI emu:emu|CHIPSET:u_CHIPSET|PERIPHERALS:u_PERIPHERALS|CGA_CRTC_OE_1}] 10 # SDRAM -set_input_delay -clock { SDRAM_CLK } -max 6 [get_ports { SDRAM_DQ[*] }] +set_input_delay -clock { SDRAM_CLK } -max 5 [get_ports { SDRAM_DQ[*] }] set_input_delay -clock { SDRAM_CLK } -min 3 [get_ports { SDRAM_DQ[*] }] set_output_delay -clock { SDRAM_CLK } -max 2 [get_ports { SDRAM_DQ[*] SDRAM_DQM* SDRAM_A[*] SDRAM_n* SDRAM_BA[*] SDRAM_CKE }] set_output_delay -clock { SDRAM_CLK } -min 1.5 [get_ports { SDRAM_DQ[*] SDRAM_DQM* SDRAM_A[*] SDRAM_n* SDRAM_BA[*] SDRAM_CKE }] diff --git a/rtl/KFPC-XT/HDL/Chipset.sv b/rtl/KFPC-XT/HDL/Chipset.sv index 76ece8c..f6355a3 100644 --- a/rtl/KFPC-XT/HDL/Chipset.sv +++ b/rtl/KFPC-XT/HDL/Chipset.sv @@ -305,10 +305,8 @@ module CHIPSET ( ); RAM u_RAM ( - .clock (clock), - .sdram_clock (sdram_clock), - .reset (reset), - .sdram_reset (sdram_reset), + .clock (sdram_clock), + .reset (sdram_reset), .enable_sdram (enable_sdram), .address (address), .internal_data_bus (internal_data_bus), diff --git a/rtl/KFPC-XT/HDL/KFSDRAM/HDL/KFSDRAM.sv b/rtl/KFPC-XT/HDL/KFSDRAM/HDL/KFSDRAM.sv index 7e11491..cb8d5cb 100644 --- a/rtl/KFPC-XT/HDL/KFSDRAM/HDL/KFSDRAM.sv +++ b/rtl/KFPC-XT/HDL/KFSDRAM/HDL/KFSDRAM.sv @@ -5,19 +5,17 @@ // Written by kitune-san // module KFSDRAM #( - // IS42S16320F-7TL (32Mx16) parameter sdram_col_width = 9, parameter sdram_row_width = 13, parameter sdram_bank_width = 2, parameter sdram_data_width = 16, parameter sdram_no_refresh = 1'b0, parameter sdram_trc = 16'd5-16'd1, - parameter sdram_tras = 16'd8-16'd1, parameter sdram_trp = 16'd1-16'd1, parameter sdram_tmrd = 16'd2-16'd1, parameter sdram_trcd = 16'd1-16'd1, parameter sdram_tdpl = 16'd2-16'd1, - parameter cas_latency = 3'b011, + parameter cas_latency = 3'b010, parameter sdram_init_wait = 16'd10000, parameter sdram_refresh_cycle = 16'd00100 ) ( @@ -57,7 +55,7 @@ module KFSDRAM #( `define BANK_ADDRESS_TOP (sdram_col_width + sdram_row_width + sdram_bank_width - 1) `define BANK_ADDRESS_BOTTOM (sdram_col_width + sdram_row_width) - typedef enum { INIT, PALL, INIT_CBR_1, INIT_CBR_2, MRS, REFRESH_PALL, REFRESH, IDLE, WRITE_ACT, WRITE, PRECHARGE_WAIT, READ_ACT, READ, PRECHARGE } state_t; + typedef enum { INIT, PALL, INIT_CBR_1, INIT_CBR_2, MRS, REFRESH_PALL, REFRESH, IDLE, WRITE, PRECHARGE_WAIT, READ, PRECHARGE } state_t; state_t state; state_t next_state; @@ -67,7 +65,6 @@ module KFSDRAM #( logic [sdram_col_width-1:0] read_counter; logic send_cmd_timing; logic end_read_cmd; - logic read_flag_tmp; // // State Machine @@ -106,16 +103,12 @@ module KFSDRAM #( end IDLE: begin if (write_request) - next_state = WRITE_ACT; + next_state = WRITE; else if (read_request) - next_state = READ_ACT; + next_state = READ; else if ((~sdram_no_refresh) && (enable_refresh) && (refresh_counter == sdram_refresh_cycle)) next_state = REFRESH_PALL; end - WRITE_ACT: begin - if (state_counter == sdram_trcd) - next_state = WRITE; - end WRITE: begin if (access_counter == (access_num - 1)) next_state = PRECHARGE_WAIT; @@ -124,10 +117,6 @@ module KFSDRAM #( if (state_counter == sdram_tdpl) next_state = PRECHARGE; end - READ_ACT: begin - if (state_counter == sdram_trcd) - next_state = READ; - end READ: begin if ((end_read_cmd) && (read_counter == access_num)) next_state = PRECHARGE; @@ -315,26 +304,39 @@ module KFSDRAM #( sdram_dq_io <= 1'b1; end IDLE : begin - sdram_address <= 0; - sdram_cke <= 1'b1; - sdram_cs <= 1'b0; - sdram_ras <= 1'b1; - sdram_cas <= 1'b1; - sdram_we <= 1'b1; - sdram_ba <= 0; - sdram_dq_out <= 0; - sdram_dq_io <= 1'b1; - end - WRITE_ACT: begin - sdram_address <= (send_cmd_timing) ? address[`ROW_ADDRESS_TOP:`ROW_ADDRESS_BOTTOM] : 0; - sdram_cke <= 1'b1; - sdram_cs <= 1'b0; - sdram_ras <= (send_cmd_timing) ? 1'b0 : 1'b1; - sdram_cas <= 1'b1; - sdram_we <= 1'b1; - sdram_ba <= (send_cmd_timing) ? address[`BANK_ADDRESS_TOP:`BANK_ADDRESS_BOTTOM] : 0; - sdram_dq_out <= 0; - sdram_dq_io <= 1'b1; + if (next_state == WRITE) begin + sdram_address <= address[`ROW_ADDRESS_TOP:`ROW_ADDRESS_BOTTOM]; + sdram_cke <= 1'b1; + sdram_cs <= 1'b0; + sdram_ras <= 1'b0; + sdram_cas <= 1'b1; + sdram_we <= 1'b1; + sdram_ba <= address[`BANK_ADDRESS_TOP:`BANK_ADDRESS_BOTTOM]; + sdram_dq_out <= 0; + sdram_dq_io <= 1'b1; + end + else if (next_state == READ) begin + sdram_address <= address[`ROW_ADDRESS_TOP:`ROW_ADDRESS_BOTTOM]; + sdram_cke <= 1'b1; + sdram_cs <= 1'b0; + sdram_ras <= 1'b0; + sdram_cas <= 1'b1; + sdram_we <= 1'b1; + sdram_ba <= address[`BANK_ADDRESS_TOP:`BANK_ADDRESS_BOTTOM]; + sdram_dq_out <= 0; + sdram_dq_io <= 1'b1; + end + else begin + sdram_address <= 0; + sdram_cke <= 1'b1; + sdram_cs <= 1'b0; + sdram_ras <= 1'b1; + sdram_cas <= 1'b1; + sdram_we <= 1'b1; + sdram_ba <= 0; + sdram_dq_out <= 0; + sdram_dq_io <= 1'b1; + end end WRITE: begin sdram_address[sdram_col_width-1:0] <= address[sdram_col_width-1:0] + access_counter; @@ -359,17 +361,6 @@ module KFSDRAM #( sdram_dq_out <= 0; sdram_dq_io <= 1'b1; end - READ_ACT: begin - sdram_address <= (send_cmd_timing) ? address[`ROW_ADDRESS_TOP:`ROW_ADDRESS_BOTTOM] : 0; - sdram_cke <= 1'b1; - sdram_cs <= 1'b0; - sdram_ras <= (send_cmd_timing) ? 1'b0 : 1'b1; - sdram_cas <= 1'b1; - sdram_we <= 1'b1; - sdram_ba <= (send_cmd_timing) ? address[`BANK_ADDRESS_TOP:`BANK_ADDRESS_BOTTOM] : 0; - sdram_dq_out <= 0; - sdram_dq_io <= 1'b1; - end READ: begin sdram_address[sdram_col_width-1:0] <= (~end_read_cmd) ? address[sdram_col_width-1:0] + access_counter : 0; sdram_address[sdram_row_width-1:sdram_col_width] <= 0; @@ -414,12 +405,7 @@ module KFSDRAM #( // // Input Data // - always_ff @(posedge sdram_clock, posedge sdram_reset) begin - if (sdram_reset) - data_out <= 0; - else - data_out <= sdram_dq_in; - end + assign data_out = sdram_dq_in; // @@ -428,13 +414,6 @@ module KFSDRAM #( assign idle = (state == IDLE); assign refresh_mode = (state == REFRESH_PALL) || (state == REFRESH); assign write_flag = (state == WRITE); - assign read_flag_tmp = (state == READ) && (next_state == READ) && (state_counter > cas_latency); - - always_ff @(posedge sdram_clock, posedge sdram_reset) begin - if (sdram_reset) - read_flag <= 1'b0; - else - read_flag <= read_flag_tmp; - end + assign read_flag = (state == READ) && (next_state == READ) && (state_counter > cas_latency); endmodule diff --git a/rtl/KFPC-XT/HDL/RAM.sv b/rtl/KFPC-XT/HDL/RAM.sv index 75bd593..36e8b83 100644 --- a/rtl/KFPC-XT/HDL/RAM.sv +++ b/rtl/KFPC-XT/HDL/RAM.sv @@ -4,9 +4,7 @@ // module RAM ( input logic clock, - input logic sdram_clock, input logic reset, - input logic sdram_reset, input logic enable_sdram, // I/O Ports input logic [19:0] address, @@ -17,8 +15,6 @@ module RAM ( input logic no_command_state, output logic memory_access_ready, output logic ram_address_select_n, - // VRAM FIFO - // TODO: // SDRAM output logic [12:0] sdram_address, output logic sdram_cke, @@ -32,131 +28,79 @@ module RAM ( output logic sdram_dq_io, output logic sdram_ldqm, output logic sdram_udqm, - // EMS - input logic [6:0] map_ems[0:3], - input logic ems_b1, - input logic ems_b2, - input logic ems_b3, - input logic ems_b4 - + // EMS + input logic [6:0] map_ems[0:3], + input logic ems_b1, + input logic ems_b2, + input logic ems_b3, + input logic ems_b4 + ); typedef enum {IDLE, RAM_WRITE_1, RAM_WRITE_2, RAM_READ_1, RAM_READ_2, COMPLETE_RAM_RW, WAIT} state_t; state_t state; state_t next_state; - logic [21:0] latch_address_ff; logic [21:0] latch_address; - logic [7:0] latch_data_ff; logic [7:0] latch_data; - logic write_command_ff_1; - logic write_command_ff_2; logic write_command; - logic read_command_ff_1; - logic read_command_ff_2; logic read_command; - logic no_command_state_ff_1; - logic no_command_state_ff_2; - logic no_command_state_ff_3; + logic prev_no_command_state; logic enable_refresh; logic access_ready; // // RAM Address Select (0x00000-0xAFFFF and 0xC0000-0xEBFFF) - // - assign ram_address_select_n = ~(enable_sdram && - ~(address[19:16] == 4'b1111) && // B0000h reserved for VRAM - ~(address[19:16] == 4'b1011) && // F0000h reserved for BIOS - ~(address[19:14] == 6'b111011)); // EC000h reserved for XTIDE - + // + assign ram_address_select_n = ~(enable_sdram && + ~(address[19:16] == 4'b1111) && // B0000h reserved for VRAM + ~(address[19:16] == 4'b1011) && // F0000h reserved for BIOS + ~(address[19:14] == 6'b111011)); // EC000h reserved for XTIDE + // - // Latch I/O Ports + // I/O Ports // // Address - always_ff @(posedge sdram_clock, posedge sdram_reset) begin - if (sdram_reset) - latch_address_ff <= 0; - else begin - - if (ems_b1) - latch_address_ff <= {1'b1, map_ems[0], address[13:0]}; - else if (ems_b2) - latch_address_ff <= {1'b1, map_ems[1], address[13:0]}; - else if (ems_b3) - latch_address_ff <= {1'b1, map_ems[2], address[13:0]}; - else if (ems_b4) - latch_address_ff <= {1'b1, map_ems[3], address[13:0]}; - else - latch_address_ff <= {2'b00, address}; - - end - - end - - always_ff @(posedge sdram_clock, posedge sdram_reset) begin - if (sdram_reset) - latch_address <= 0; + always_comb begin + if (ems_b1) + latch_address = {1'b1, map_ems[0], address[13:0]}; + else if (ems_b2) + latch_address = {1'b1, map_ems[1], address[13:0]}; + else if (ems_b3) + latch_address = {1'b1, map_ems[2], address[13:0]}; + else if (ems_b4) + latch_address = {1'b1, map_ems[3], address[13:0]}; else - latch_address <= latch_address_ff; + latch_address = {2'b00, address}; end - // Data Bus - always_ff @(posedge sdram_clock, posedge sdram_reset) begin - if (sdram_reset) begin - latch_data_ff <= 0; + // Data + always_ff @(posedge clock, posedge reset) begin + if (reset) latch_data <= 0; - end - else begin - latch_data_ff <= internal_data_bus; - latch_data <= latch_data_ff; - end + else + latch_data <= internal_data_bus; end // Write Command - always_ff @(posedge sdram_clock, posedge sdram_reset) begin - if (sdram_reset) begin - write_command_ff_1 <= 1'b0; - write_command_ff_2 <= 1'b0; - write_command <= 1'b0; - end - else begin - write_command_ff_1 <= ~ram_address_select_n & ~memory_write_n; - write_command_ff_2 <= write_command_ff_1; - write_command <= write_command_ff_2; - end - end + assign write_command = ~ram_address_select_n & ~memory_write_n; // Read Command - always_ff @(posedge sdram_clock, posedge sdram_reset) begin - if (sdram_reset) begin - read_command_ff_1 <= 1'b0; - read_command_ff_2 <= 1'b0; - read_command <= 1'b0; - end - else begin - read_command_ff_1 <= ~ram_address_select_n & ~memory_read_n; - read_command_ff_2 <= read_command_ff_1; - read_command <= read_command_ff_2; - end - end + assign read_command = ~ram_address_select_n & ~memory_read_n; // Generate refresh timing - always_ff @(posedge sdram_clock, posedge sdram_reset) begin - if (sdram_reset) begin - no_command_state_ff_1 <= 1'b0; - no_command_state_ff_2 <= 1'b0; - no_command_state_ff_3 <= 1'b0; + always_ff @(posedge clock, posedge reset) begin + if (reset) begin + prev_no_command_state <= 1'b0; end else begin - no_command_state_ff_1 <= no_command_state; - no_command_state_ff_2 <= no_command_state_ff_1; - no_command_state_ff_3 <= no_command_state_ff_2; + prev_no_command_state <= no_command_state; end end - assign enable_refresh = no_command_state_ff_2 & ~no_command_state_ff_3; + assign enable_refresh = no_command_state & ~prev_no_command_state; // @@ -174,8 +118,8 @@ module RAM ( logic refresh_mode; KFSDRAM u_KFSDRAM ( - .sdram_clock (sdram_clock), - .sdram_reset (sdram_reset), + .sdram_clock (clock), + .sdram_reset (reset), .address (access_address), .access_num (access_num), .data_in (access_data_in), @@ -247,8 +191,8 @@ module RAM ( endcase end - always_ff @(posedge sdram_clock, posedge sdram_reset) begin - if (sdram_reset) + always_ff @(posedge clock, posedge reset) begin + if (reset) state = IDLE; else state = next_state; @@ -261,11 +205,11 @@ module RAM ( always_comb begin casez (state) IDLE: begin - access_address = 25'h0000000; - access_num = 10'h000; - access_data_in = 16'h0000; - write_request = 1'b0; - read_request = 1'b0; + access_address = {7'h00, latch_address}; + access_num = 10'h001; + access_data_in = {8'h00, latch_data}; + write_request = write_command ? 1'b1 : 1'b0; + read_request = read_command ? 1'b1 : 1'b0; sdram_ldqm = 1'b0; sdram_udqm = 1'b0; end @@ -330,32 +274,23 @@ module RAM ( // // Databus Out // - logic [15:0] data_out_tmp; - - always_ff @(posedge sdram_clock, posedge sdram_reset) begin - if (sdram_reset) - data_out_tmp <= 0; - else if (read_flag) - data_out_tmp <= access_data_out; - else if (read_command) - data_out_tmp <= data_out_tmp; - else - data_out_tmp <= 0; - end - always_ff @(posedge clock, posedge reset) begin if (reset) data_bus_out <= 0; + else if (read_flag) + data_bus_out <= access_data_out[7:0]; + else if (read_command) + data_bus_out <= data_bus_out; else - data_bus_out <= data_out_tmp[7:0]; + data_bus_out <= 0; end // // Ready/Wait Signal // - always_ff @(posedge sdram_clock, posedge sdram_reset) begin - if (sdram_reset) + always_ff @(posedge clock, posedge reset) begin + if (reset) access_ready <= 1'b0; else if (state == COMPLETE_RAM_RW) access_ready <= 1'b1;