From ab284a598a16f39360e5bc5899b084642dac2dde Mon Sep 17 00:00:00 2001 From: sorgelig Date: Thu, 23 Aug 2018 21:48:21 +0800 Subject: [PATCH] Update SDRAM controller and arbiter. --- TSConf-lite.qsf | 2 +- TSConf.qsf | 2 +- TSConf.sv | 8 +- src/memory/arbiter.v | 301 ++++++++++++++++++++----------------------- src/sdram.v | 120 +++++++++++++++++ src/sdram.vhd | 165 ------------------------ src/tsconf.v | 65 +++++----- sys/sys_top.sdc | 5 +- 8 files changed, 299 insertions(+), 369 deletions(-) create mode 100644 src/sdram.v delete mode 100644 src/sdram.vhd diff --git a/TSConf-lite.qsf b/TSConf-lite.qsf index 571265a..d8ecb04 100644 --- a/TSConf-lite.qsf +++ b/TSConf-lite.qsf @@ -392,7 +392,7 @@ set_global_assignment -name VERILOG_FILE src/video/video_top.v set_global_assignment -name VHDL_FILE src/keyboard.vhd set_global_assignment -name VERILOG_FILE src/kempston_mouse.v set_global_assignment -name VERILOG_FILE src/spi.v -set_global_assignment -name VHDL_FILE src/sdram.vhd +set_global_assignment -name VERILOG_FILE src/sdram.v set_global_assignment -name VERILOG_FILE src/clock.v set_global_assignment -name VERILOG_FILE src/tsconf.v set_global_assignment -name SYSTEMVERILOG_FILE ddram.sv diff --git a/TSConf.qsf b/TSConf.qsf index 2c173e4..a2f85a9 100644 --- a/TSConf.qsf +++ b/TSConf.qsf @@ -391,7 +391,7 @@ set_global_assignment -name VERILOG_FILE src/video/video_top.v set_global_assignment -name VHDL_FILE src/keyboard.vhd set_global_assignment -name VERILOG_FILE src/kempston_mouse.v set_global_assignment -name VERILOG_FILE src/spi.v -set_global_assignment -name VHDL_FILE src/sdram.vhd +set_global_assignment -name VERILOG_FILE src/sdram.v set_global_assignment -name VERILOG_FILE src/clock.v set_global_assignment -name VERILOG_FILE src/tsconf.v set_global_assignment -name SYSTEMVERILOG_FILE ddram.sv diff --git a/TSConf.sv b/TSConf.sv index 5084b78..31429e0 100644 --- a/TSConf.sv +++ b/TSConf.sv @@ -259,11 +259,11 @@ tsconf tsconf .SDRAM_BA(SDRAM_BA), .SDRAM_DQML(SDRAM_DQML), .SDRAM_DQMH(SDRAM_DQMH), - .SDRAM_WE_N(SDRAM_nWE), - .SDRAM_CAS_N(SDRAM_nCAS), - .SDRAM_RAS_N(SDRAM_nRAS), + .SDRAM_nWE(SDRAM_nWE), + .SDRAM_nCAS(SDRAM_nCAS), + .SDRAM_nRAS(SDRAM_nRAS), .SDRAM_CKE(SDRAM_CKE), - .SDRAM_CS_N(SDRAM_nCS), + .SDRAM_nCS(SDRAM_nCS), .VGA_R(R), .VGA_G(G), diff --git a/src/memory/arbiter.v b/src/memory/arbiter.v index 97c3fda..2017a5c 100644 --- a/src/memory/arbiter.v +++ b/src/memory/arbiter.v @@ -49,206 +49,185 @@ // - DMA - CPU -module arbiter( +module arbiter +( - input wire clk, - input wire c0, - input wire c1, - input wire c2, - input wire c3, + input clk, + input c0, + input c1, + input c2, + input c3, -// dram.v interface - output wire [23:0] dram_addr, // address for dram access - output wire dram_req, // dram request - output wire dram_rnw, // Read-NotWrite - output wire [ 1:0] dram_bsel, // byte select: bsel[1] for wrdata[15:8], bsel[0] for wrdata[7:0] - output wire [15:0] dram_wrdata, // data to be written + // dram.v interface + output [20:0] dram_addr, // address for dram access + output dram_req, // dram request + output dram_rnw, // Read-NotWrite + output [ 1:0] dram_bsel, // byte select: bsel[1] for wrdata[15:8], bsel[0] for wrdata[7:0] + output [15:0] dram_wrdata, // data to be written -// video - input wire [23:0] video_addr, // during access block, only when video_strobe==1 - input wire go, // start video access blocks - input wire [ 4:0] video_bw, // [4:3] - total cycles: 11 = 8 / 01 = 4 / 00 = 2 + // video + input [20:0] video_addr, // during access block, only when video_strobe==1 + input go, // start video access blocks + input [ 4:0] video_bw, // [4:3] - total cycles: 11 = 8 / 01 = 4 / 00 = 2 // [2:0] - need cycles - output wire video_pre_next, // (c1) - output wire video_next, // (c2) at this signal video_addr may be changed; it is one clock leading the video_strobe - output wire video_strobe, // (c3) one-cycle strobe meaning that video_data is available - output wire video_next_strobe, // (c3) one-cycle strobe meaning that video_data is available - output wire next_vid, // used for TM prefetch - -// CPU - input wire [23:0] cpu_addr, - input wire [ 7:0] cpu_wrdata, - input wire cpu_req, - input wire cpu_rnw, - input wire cpu_wrbsel, - output reg cpu_next, // next cycle is allowed to be used by CPU - output reg cpu_strobe, // c2 strobe - output reg cpu_latch, // c2-c3 strobe - output wire curr_cpu_o, // -// DMA - input wire [23:0] dma_addr, - input wire [15:0] dma_wrdata, - input wire dma_req, - input wire dma_rnw, - output wire dma_next, + output video_pre_next, // (c1) + output video_next, // (c2) at this signal video_addr may be changed; it is one clock leading the video_strobe + output video_strobe, // (c3) one-cycle strobe meaning that video_data is available + output video_next_strobe, // (c3) one-cycle strobe meaning that video_data is available + output next_vid, // used for TM prefetch -// TS - input wire [23:0] ts_addr, - input wire ts_req, - output wire ts_pre_next, - output wire ts_next, + // CPU + input [20:0] cpu_addr, + input [ 7:0] cpu_wrdata, + input cpu_req, + input cpu_rnw, + input cpu_wrbsel, + output reg cpu_next, // next cycle is allowed to be used by CPU + output reg cpu_strobe, // c2 strobe + output reg cpu_latch, // c2-c3 strobe + output curr_cpu_o, + // DMA + input [20:0] dma_addr, + input [15:0] dma_wrdata, + input dma_req, + input dma_rnw, + output dma_next, -// TM - input wire [23:0] tm_addr, - input wire tm_req, - output wire tm_next, - -//----- - output wire [7:0] TST + // TS + input [20:0] ts_addr, + input ts_req, + output ts_pre_next, + output ts_next, + // TM + input [20:0] tm_addr, + input tm_req, + output tm_next ); - assign curr_cpu_o = curr_cpu; - - assign TST[0] = curr_dma; - assign TST[1] = curr_cpu; - assign TST[2] = dram_rnw; - assign TST[7:3] = 5'b00000; +assign curr_cpu_o = curr_cpu; - localparam CYCLES = 5; - - localparam CYC_CPU = 5'b00001; - localparam CYC_VID = 5'b00010; - localparam CYC_TS = 5'b00100; - localparam CYC_TM = 5'b01000; - localparam CYC_DMA = 5'b10000; - localparam CYC_FREE = 5'b00000; +localparam CYCLES = 5; - localparam CPU = 0; - localparam VIDEO = 1; - localparam TS = 2; - localparam TM = 3; - localparam DMA = 4; - - reg [CYCLES-1:0] curr_cycle; // type of the cycle in progress - reg [CYCLES-1:0] next_cycle; // type of the next cycle +localparam CYC_CPU = 5'b00001; +localparam CYC_VID = 5'b00010; +localparam CYC_TS = 5'b00100; +localparam CYC_TM = 5'b01000; +localparam CYC_DMA = 5'b10000; +localparam CYC_FREE = 5'b00000; - wire next_cpu = next_cycle[CPU]; - assign next_vid = next_cycle[VIDEO]; -// wire next_ts = next_cycle[TS]; -// wire next_tm = next_cycle[TM]; - wire next_dma = next_cycle[DMA]; +localparam CPU = 0; +localparam VIDEO = 1; +localparam TS = 2; +localparam TM = 3; +localparam DMA = 4; - wire curr_cpu = curr_cycle[CPU]; - wire curr_vid = curr_cycle[VIDEO]; - wire curr_ts = curr_cycle[TS]; - wire curr_tm = curr_cycle[TM]; - wire curr_dma = curr_cycle[DMA]; +reg [CYCLES-1:0] curr_cycle; // type of the cycle in progress +reg [CYCLES-1:0] next_cycle; // type of the next cycle + +wire next_cpu = next_cycle[CPU]; +assign next_vid = next_cycle[VIDEO]; +wire next_ts = next_cycle[TS]; +wire next_tm = next_cycle[TM]; +wire next_dma = next_cycle[DMA]; + +wire curr_cpu = curr_cycle[CPU]; +wire curr_vid = curr_cycle[VIDEO]; +wire curr_ts = curr_cycle[TS]; +wire curr_tm = curr_cycle[TM]; +wire curr_dma = curr_cycle[DMA]; // track blk_rem counter: // how many cycles left to the end of block (7..0) - wire [2:0] blk_nrem = (video_start && go) ? {video_bw[4:3], 1'b1} : (video_start ? 3'd0 : (blk_rem - 3'd1)); - wire bw_full = ~|{video_bw[4] & video_bw[2], video_bw[3] & video_bw[1], video_bw[0]}; // stall when 000/00/0 - wire video_start = ~|blk_rem; - wire video_only = stall || (vid_rem == blk_rem); - wire video_idle = ~|vid_rem; +wire [2:0] blk_nrem = (video_start && go) ? {video_bw[4:3], 1'b1} : (video_start ? 3'd0 : (blk_rem - 3'd1)); +wire bw_full = ~|{video_bw[4] & video_bw[2], video_bw[3] & video_bw[1], video_bw[0]}; // stall when 000/00/0 +wire video_start = ~|blk_rem; +wire video_only = stall || (vid_rem == blk_rem); +wire video_idle = ~|vid_rem; - reg [2:0] blk_rem; // remaining accesses in a block (7..0) - reg stall; - always @(posedge clk) if (c3) - begin +reg [2:0] blk_rem; // remaining accesses in a block (7..0) +reg stall; +always @(posedge clk) begin + if (c3) begin blk_rem <= blk_nrem; - if (video_start) - stall <= bw_full & go; - end + if (video_start) stall <= bw_full & go; + end +end // track vid_rem counter // how many video cycles left to the end of block (7..0) - wire [2:0] vid_nrem = (go && video_start) ? vid_nrem_start : (next_vid ? vid_nrem_next : vid_rem); - wire [2:0] vid_nrem_start = (cpu_req && !dev_over_cpu) ? vidmax : (vidmax - 3'd1); - wire [2:0] vid_nrem_next = video_idle ? 3'd0 : (vid_rem - 3'd1); - wire [2:0] vidmax = {video_bw[2:0]}; // number of cycles for video access +wire [2:0] vid_nrem = (go && video_start) ? vid_nrem_start : (next_vid ? vid_nrem_next : vid_rem); +wire [2:0] vid_nrem_start = (cpu_req && !dev_over_cpu) ? vidmax : (vidmax - 3'd1); +wire [2:0] vid_nrem_next = video_idle ? 3'd0 : (vid_rem - 3'd1); +wire [2:0] vidmax = {video_bw[2:0]}; // number of cycles for video access - reg [2:0] vid_rem; // remaining video accesses in block - always @(posedge clk) if (c3) - vid_rem <= vid_nrem; +reg [2:0] vid_rem; // remaining video accesses in block +always @(posedge clk) if (c3) vid_rem <= vid_nrem; // next cycle decision - wire [CYCLES-1:0] cyc_dev = tm_req ? CYC_TM : (ts_req ? CYC_TS : CYC_DMA); - wire dev_req = ts_req || tm_req || dma_req; - // wire dev_over_cpu = (((ts_req || tm_req) && ts_z80_lp) || (dma_req && dma_z80_lp)) && int_n; // CPU gets higher priority to acknowledge the INT - wire dev_over_cpu = 0; +wire [CYCLES-1:0] cyc_dev = tm_req ? CYC_TM : (ts_req ? CYC_TS : CYC_DMA); +wire dev_req = ts_req || tm_req || dma_req; +// wire dev_over_cpu = (((ts_req || tm_req) && ts_z80_lp) || (dma_req && dma_z80_lp)) && int_n; // CPU gets higher priority to acknowledge the INT +wire dev_over_cpu = 0; - always @* - if (video_start) // video burst start - if (go) // video active line - 38us-ON, 26us-ON - begin - cpu_next = dev_over_cpu ? 1'b0 : !bw_full; - next_cycle = dev_over_cpu ? CYC_VID : (bw_full ? CYC_VID : (cpu_req ? CYC_CPU : CYC_VID)); - end - - else // video idle - begin - cpu_next = !dev_over_cpu; - next_cycle = dev_over_cpu ? cyc_dev : (cpu_req ? CYC_CPU : (dev_req ? cyc_dev : CYC_FREE)); - end - - else // video burst in progress - begin - cpu_next = dev_over_cpu ? 1'b0 : !video_only; - next_cycle = video_only ? CYC_VID : (dev_over_cpu ? cyc_dev : (cpu_req ? CYC_CPU : (!video_idle ? CYC_VID : (dev_req ? cyc_dev : CYC_FREE)))); +always @* begin + if (video_start) begin // video burst start + if (go) begin // video active line - 38us-ON, 26us-ON + cpu_next = dev_over_cpu ? 1'b0 : !bw_full; + next_cycle = dev_over_cpu ? CYC_VID : (bw_full ? CYC_VID : (cpu_req ? CYC_CPU : CYC_VID)); end + else begin // video idle + cpu_next = !dev_over_cpu; + next_cycle = dev_over_cpu ? cyc_dev : (cpu_req ? CYC_CPU : (dev_req ? cyc_dev : CYC_FREE)); + end + end + else begin // video burst in progress + cpu_next = dev_over_cpu ? 1'b0 : !video_only; + next_cycle = video_only ? CYC_VID : (dev_over_cpu ? cyc_dev : (cpu_req ? CYC_CPU : (!video_idle ? CYC_VID : (dev_req ? cyc_dev : CYC_FREE)))); + end +end + +always @(posedge clk) if (c3) curr_cycle <= next_cycle; - always @(posedge clk) if (c3) - curr_cycle <= next_cycle; // DRAM interface - assign dram_wrdata = curr_dma ? dma_wrdata : {2{cpu_wrdata[7:0]}}; // write data has to be clocked at c0 in dram.v - //assign dram_wrdata = curr_dma ? 16'h0000 : {2{cpu_wrdata[7:0]}}; // write data has to be clocked at c0 in dram.v - assign dram_bsel[1:0] = curr_dma ? 2'b11 : {cpu_wrbsel, ~cpu_wrbsel}; - assign dram_addr = {24{curr_cpu}} & cpu_addr - | {24{curr_vid}} & video_addr - | {24{curr_ts}} & ts_addr - | {24{curr_tm}} & tm_addr - | {24{curr_dma}} & dma_addr; - //==================================================== - assign dram_req = |next_cycle; //for c3=1, rising edge - assign dram_rnw = next_cpu ? cpu_rnw : (next_dma ? dma_rnw : 1'b1); - //assign dram_req = |curr_cycle; - //assign dram_rnw = curr_cpu ? cpu_rnw : (curr_dma ? dma_rnw : 1'b1); - +assign dram_wrdata= curr_dma ? dma_wrdata : {cpu_wrdata,cpu_wrdata}; // write data has to be clocked at c0 in dram.v +assign dram_bsel = {cpu_wrbsel | next_dma, ~cpu_wrbsel | next_dma}; +assign dram_req = |next_cycle; +assign dram_rnw = next_cpu ? cpu_rnw : ~next_dma | dma_rnw; +assign dram_addr = {21{next_cpu}} & cpu_addr + | {21{next_vid}} & video_addr + | {21{next_ts }} & ts_addr + | {21{next_tm }} & tm_addr + | {21{next_dma}} & dma_addr; - reg cpu_rnw_r; - always @(posedge clk) if (c3) - cpu_rnw_r <= cpu_rnw; +reg cpu_rnw_r; +always @(posedge clk) if (c3) cpu_rnw_r <= cpu_rnw; // generation of read strobes: for video and cpu - always @(posedge clk) - if (c1) - begin - cpu_strobe <= curr_cpu && cpu_rnw_r; - cpu_latch <= curr_cpu && cpu_rnw_r; - end - else if (c2) - cpu_strobe <= 1'b0; - else if (c3) - cpu_latch <= 1'b0; +always @(posedge clk) begin + if (c1) begin + cpu_strobe <= curr_cpu && cpu_rnw_r; + cpu_latch <= curr_cpu && cpu_rnw_r; + end + else if (c2) cpu_strobe <= 1'b0; + else if (c3) cpu_latch <= 1'b0; +end +assign video_pre_next = curr_vid & c1; +assign video_next = curr_vid & c2; +assign video_strobe = curr_vid && c3; +assign video_next_strobe = next_vid && c3; - assign video_pre_next = curr_vid & c1; - assign video_next = curr_vid & c2; - assign video_strobe = curr_vid && c3; - assign video_next_strobe = next_vid && c3; +assign ts_pre_next = curr_ts & c1; +assign ts_next = curr_ts & c2; - assign ts_pre_next = curr_ts & c1; - assign ts_next = curr_ts & c2; - - assign tm_next = curr_tm & c2; +assign tm_next = curr_tm & c2; - assign dma_next = curr_dma & c2; +assign dma_next = curr_dma & c2; endmodule diff --git a/src/sdram.v b/src/sdram.v new file mode 100644 index 0000000..4fcafb3 --- /dev/null +++ b/src/sdram.v @@ -0,0 +1,120 @@ + +module sdram +( + // Memory port + input clk, + input cyc, + + input curr_cpu, + input [1:0] bsel, // Active HI + input [23:0] A, + input [15:0] DI, + output reg [15:0] DO, + output reg [15:0] DO_cpu, + input REQ, + input RNW, + + // SDRAM Pin + inout reg [15:0] SDRAM_DQ, + output reg [12:0] SDRAM_A, + output reg [1:0] SDRAM_BA, + output reg SDRAM_DQML, + output reg SDRAM_DQMH, + output SDRAM_nCS, + output SDRAM_nCAS, + output SDRAM_nRAS, + output SDRAM_nWE, + output SDRAM_CKE +); + +reg [2:0] sdr_cmd; + +localparam SdrCmd_xx = 3'b111; // no operation +localparam SdrCmd_ac = 3'b011; // activate +localparam SdrCmd_rd = 3'b101; // read +localparam SdrCmd_wr = 3'b100; // write +localparam SdrCmd_pr = 3'b010; // precharge all +localparam SdrCmd_re = 3'b001; // refresh +localparam SdrCmd_ms = 3'b000; // mode regiser set + +always @(posedge clk) begin + reg [4:0] state; + reg rd; + reg [8:0] col; + + case (state) + + // Init + 'h00: begin + sdr_cmd <= SdrCmd_pr; // PRECHARGE + SDRAM_DQ <= 16'bZZZZZZZZZZZZZZZZ; + SDRAM_A <= 0; + SDRAM_BA <= 0; + SDRAM_DQML <= 1; + SDRAM_DQMH <= 1; + state <= state + 1'd1; + end + + // REFRESH + 'h03, 'h0A: begin + sdr_cmd <= SdrCmd_re; + state <= state + 1'd1; + end + + // LOAD MODE REGISTER + 'h11: begin + sdr_cmd <= SdrCmd_ms; + SDRAM_A <= {3'b000, 1'b1, 2'b00, 3'b010, 1'b0, 3'b000}; + state <= state + 1'd1; + end + + // Idle + 'h18: begin + rd <= 0; + if (rd) begin + DO <= SDRAM_DQ; + if (curr_cpu) DO_cpu <= SDRAM_DQ; + end + if(cyc) begin + if (REQ) begin + sdr_cmd <= SdrCmd_ac; // ACTIVE + {SDRAM_A,SDRAM_BA,col} <= A; + SDRAM_DQML <= ~(bsel[0] | RNW); + SDRAM_DQMH <= ~(bsel[1] | RNW); + rd <= RNW; + state <= state + 1'd1; + end else begin + sdr_cmd <= SdrCmd_re; // REFRESH + state <= 'h13; + end + end + end + + // Single read/write - with auto precharge + 'h1A: begin + SDRAM_A <= {4'b0010, col}; // A10 = 1 enable auto precharge; A9..0 = column + state <= 'h16; + if (rd) sdr_cmd <= SdrCmd_rd; // READ + else begin + sdr_cmd <= SdrCmd_wr; // WRITE + SDRAM_DQ <= DI; + end + end + + // NOP + default: + begin + SDRAM_DQ <= 16'bZZZZZZZZZZZZZZZZ; + sdr_cmd <= SdrCmd_xx; + state <= state + 1'd1; + end + endcase +end + +assign SDRAM_CKE = 1; +assign SDRAM_nCS = 0; +assign SDRAM_nRAS = sdr_cmd[2]; +assign SDRAM_nCAS = sdr_cmd[1]; +assign SDRAM_nWE = sdr_cmd[0]; + +endmodule diff --git a/src/sdram.vhd b/src/sdram.vhd deleted file mode 100644 index 6bbecc6..0000000 --- a/src/sdram.vhd +++ /dev/null @@ -1,165 +0,0 @@ --------------------------------------------------------------------[03.08.2014] --- SDRAM Controller -------------------------------------------------------------------------------- --- V1.0 03.08.2014 Initial release --- modified for 8Mb SDRAM 15.03.2015 (Ivan Gorodetsky) - --- CLK = 84 MHz = 11.9 ns --- WR/RD = 5T = 59.5 ns --- RFSH = 6T = 71.4 ns - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -entity sdram is -port( - CLK : in std_logic; - clk_28MHz: in std_logic; - c0 : in std_logic; - c3 : in std_logic; - - -- Memory port - loader : in std_logic; - bsel : in std_logic_vector(1 downto 0); -- Active HI - A : in std_logic_vector(23 downto 0); - DI : in std_logic_vector(15 downto 0); - DO : out std_logic_vector(15 downto 0); - curr_cpu : in std_logic; - DO_cpu : out std_logic_vector(15 downto 0); - REQ : in std_logic; - RNW : in std_logic; - - -- SDRAM Pin - CKE : out std_logic; - RAS_n : out std_logic; - CAS_n : out std_logic; - WE_n : out std_logic; - CS_n : out std_logic; - BA : out std_logic_vector(1 downto 0); - MA : out std_logic_vector(12 downto 0); - DQ : inout std_logic_vector(15 downto 0); - DQML : out std_logic; - DQMH : out std_logic -); -end sdram; - -architecture rtl of sdram is - signal state : unsigned(4 downto 0) := "00000"; - signal col : std_logic_vector(7 downto 0); - - signal WR_in : std_logic; - signal RD_in : std_logic; - signal REQ_in : std_logic; - signal RNW_in : std_logic; - signal rd_op : std_logic; - signal RFSH_in : std_logic; - signal sdr_cmd : std_logic_vector(2 downto 0); - - constant SdrCmd_xx : std_logic_vector(2 downto 0) := "111"; -- no operation - constant SdrCmd_ac : std_logic_vector(2 downto 0) := "011"; -- activate - constant SdrCmd_rd : std_logic_vector(2 downto 0) := "101"; -- read - constant SdrCmd_wr : std_logic_vector(2 downto 0) := "100"; -- write - constant SdrCmd_pr : std_logic_vector(2 downto 0) := "010"; -- precharge all - constant SdrCmd_re : std_logic_vector(2 downto 0) := "001"; -- refresh - constant SdrCmd_ms : std_logic_vector(2 downto 0) := "000"; -- mode regiser set - --- Init------------------------------------------------------------------- Idle Read------- Write------ Refresh------- --- 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 16 17 1B 1C 16 17 13 14 15 16 17 --- pr xx xx re xx xx xx xx xx xx re xx xx xx xx xx xx ms xx xx xx xx xx xx xx/ac/re xx rd xx xx xx wr xx xx xx xx xx xx xx - -begin - - process (clk_28MHz) - begin - if rising_edge (clk_28MHz) then - if c3 = '1' then --next_cycle - RD_in <= REQ and RNW; - WR_in <= REQ and not RNW; - RFSH_in <= not REQ; - end if; - - if c0 = '1' then --NOT WORK - RD_in <= '0'; - WR_in <= '0'; - RFSH_in <= '0'; - end if; - end if; - end process; - - process (CLK) - begin - if rising_edge(CLK) then - --------------------------------------------------------- - case state is - -- Init - when "00000" => -- s00 - sdr_cmd <= SdrCmd_pr; -- PRECHARGE - DQ <= (others => 'Z'); - MA <= (others => '1'); - BA <= "00"; - DQML <= '1'; - DQMH <= '1'; - state <= state + 1; - - when "00011" | "01010" => -- s03 s0A - sdr_cmd <= SdrCmd_re; -- REFRESH - state <= state + 1; - - when "10001" => -- s11 - sdr_cmd <= SdrCmd_ms; -- LOAD MODE REGISTER - MA <= "000" & "1" & "00" & "010" & "0" & "000"; - state <= state + 1; - - -- Idle - when "11000" => -- s18 - rd_op <= '0'; - if rd_op = '1' then - DO <= DQ; - if curr_cpu = '1' then - DO_cpu <= DQ; - end if; - end if; - if RD_in = '1' or (WR_in = '1' and (loader = '1' or A(23) = '0')) then - col <= A(7 downto 0); -- LOCK COL - sdr_cmd <= SdrCmd_ac; -- ACTIVE - BA <= A(10 downto 9); - MA <= "0"&A(23)&A(20 downto 11)&A(8); -- RAW_ADDR(12..0) - DQML <= not (bsel(0) or RD_in); - DQMH <= not (bsel(1) or RD_in); - rd_op <= RD_in; - state <= state + 1; - elsif RFSH_in = '1' then - sdr_cmd <= SdrCmd_re; -- REFRESH - state <= "10011"; -- s13 - end if; - - -- A24 A23 A22 A21 A20 A19 A18 A17 A16 A15 A14 A13 A12 A11 A10 A9 A8 A7 A6 A5 A4 A3 A2 A1 A0 - -- -----------------------ROW------------------------- BA1 BA0 -----------COLUMN------------ - - -- Single read/write - with auto precharge - when "11010" => -- s1A - MA <= "00100" & col; -- A10 = 1 enable auto precharge; A9..0 = column - state <= "10110"; -- s16 - if rd_op = '1' then - sdr_cmd <= SdrCmd_rd; -- READ - else - sdr_cmd <= SdrCmd_wr; -- WRITE - DQ <= DI; - end if; - - when others => - DQ <= (others => 'Z'); - sdr_cmd <= SdrCmd_xx; -- NOP - state <= state + 1; - end case; - end if; - end process; - - CKE <= '1'; - CS_n <= '0'; - RAS_n <= sdr_cmd(2); - CAS_n <= sdr_cmd(1); - WE_n <= sdr_cmd(0); - -end rtl; \ No newline at end of file diff --git a/src/tsconf.v b/src/tsconf.v index 0b0c8df..3da28ec 100644 --- a/src/tsconf.v +++ b/src/tsconf.v @@ -65,11 +65,11 @@ module tsconf output [1:0] SDRAM_BA, output SDRAM_DQML, output SDRAM_DQMH, - output SDRAM_WE_N, - output SDRAM_CAS_N, - output SDRAM_RAS_N, + output SDRAM_nCS, + output SDRAM_nCAS, + output SDRAM_nRAS, + output SDRAM_nWE, output SDRAM_CKE, - output SDRAM_CS_N, // VGA output [7:0] VGA_R, @@ -148,7 +148,7 @@ wire curr_cpu; // SDRAM wire [7:0] sdr_do_bus; wire [15:0] sdr_do_bus_16; -wire [15:0] sdr2cpu_do_bus_16; +wire [15:0] sdr_do_bus_16cpu; wire sdr_wr; wire sdr_rd; wire req; @@ -484,7 +484,7 @@ zmem TS06 .cpu_req(cpu_req), .cpu_addr(cpu_addr_20), .cpu_wrbsel(cpu_wrbsel), // for 16bit data - .cpu_rddata(sdr2cpu_do_bus_16), + .cpu_rddata(sdr_do_bus_16cpu), .cpu_next(cpu_next), .cpu_strobe(cpu_strobe), // from ARBITER ACTIVE=HI .cpu_latch(cpu_latch), @@ -506,32 +506,32 @@ arbiter TS07 .dram_rnw(dram_rnw), .dram_bsel(dram_bsel), .dram_wrdata(dram_wrdata), // data to be written - .video_addr({3'b000, video_addr}), // during access block, only when video_strobe==1 + .video_addr(video_addr), // during access block, only when video_strobe==1 .go(go_arbiter), // start video access blocks .video_bw(video_bw), // ZX="11001", [4:3] -total cycles: 11 = 8 / 01 = 4 / 00 = 2 .video_pre_next(video_pre_next), .video_next(video_next), // (c2) at this signal video_addr may be changed; it is one clock leading the video_strobe .video_strobe(video_strobe), // (c3) one-cycle strobe meaning that video_data is available .next_vid(next_video), // used for TM prefetch - .cpu_addr({csvrom, 2'b00, cpu_addr_20}), + .cpu_addr(cpu_addr_20), .cpu_wrdata(cpu_do_bus), .cpu_req(cpu_req), - .cpu_rnw(rd), + .cpu_rnw(rd | csvrom), .cpu_wrbsel(cpu_wrbsel), .cpu_next(cpu_next), // next cycle is allowed to be used by CPU .cpu_strobe(cpu_strobe), // c2 strobe .cpu_latch(cpu_latch), // c2-c3 strobe .curr_cpu_o(curr_cpu), - .dma_addr({3'b000, dma_addr}), + .dma_addr(dma_addr), .dma_wrdata(dma_wrdata), .dma_req(dma_req), .dma_rnw(dma_rnw), .dma_next(dma_next), - .ts_addr({3'b000, ts_addr}), + .ts_addr(ts_addr), .ts_req(ts_req), .ts_pre_next(ts_pre_next), .ts_next(ts_next), - .tm_addr({3'b000, tm_addr}), + .tm_addr(tm_addr), .tm_req(tm_req), .tm_next(tm_next) ); @@ -696,28 +696,27 @@ dpram #(.ADDRWIDTH(16), .MEM_INIT_FILE("tsbios.mif")) BIOS sdram SE4 ( .clk(clk), - .clk_28mhz(clk_28mhz), - .c0(c0), - .c3(c3), - .curr_cpu(curr_cpu), // from arbiter for luch DO_cpu - .loader(0), // loader = 1: wr to ROM + .cyc(ce&c3), + + .curr_cpu(curr_cpu), .bsel(dram_bsel), - .a(dram_addr), - .di(dram_wrdata), - .do(sdr_do_bus_16), - .do_cpu(sdr2cpu_do_bus_16), - .req(dram_req), - .rnw(dram_rnw), - .cke(SDRAM_CKE), - .ras_n(SDRAM_RAS_N), - .cas_n(SDRAM_CAS_N), - .we_n(SDRAM_WE_N), - .cs_n(SDRAM_CS_N), - .ba(SDRAM_BA), - .ma(SDRAM_A), - .dq(SDRAM_DQ[15:0]), - .dqml(SDRAM_DQML), - .dqmh(SDRAM_DQMH) + .A(dram_addr), + .DI(dram_wrdata), + .DO(sdr_do_bus_16), + .DO_cpu(sdr_do_bus_16cpu), + .REQ(dram_req), + .RNW(dram_rnw), + + .SDRAM_DQ(SDRAM_DQ), + .SDRAM_A(SDRAM_A), + .SDRAM_BA(SDRAM_BA), + .SDRAM_DQML(SDRAM_DQML), + .SDRAM_DQMH(SDRAM_DQMH), + .SDRAM_nCS(SDRAM_nCS), + .SDRAM_nCAS(SDRAM_nCAS), + .SDRAM_nRAS(SDRAM_nRAS), + .SDRAM_nWE(SDRAM_nWE), + .SDRAM_CKE(SDRAM_CKE) ); diff --git a/sys/sys_top.sdc b/sys/sys_top.sdc index bcebaaa..a15d3f8 100644 --- a/sys/sys_top.sdc +++ b/sys/sys_top.sdc @@ -16,9 +16,6 @@ create_generated_clock -source [get_pins -compatibility_mode {pll_hdmi|pll_hdmi_ create_generated_clock -source [get_pins { pll_hdmi|pll_hdmi_inst|altera_pll_i|cyclonev_pll|counter[0].output_counter|divclk}] \ -name VID_CLK -divide_by 2 -duty_cycle 50 [get_nets {vip|output_inst|vid_clk}] -create_generated_clock -source [get_pins -compatibility_mode {*|pll|pll_inst|altera_pll_i|general[3].gpll~PLL_OUTPUT_COUNTER|divclk}] \ - -name ZCLK -divide_by 2 -duty_cycle 50 [get_nets {emu:emu|tsconf:tsconf|zclock:TS02|zclk_o}] - derive_clock_uncertainty @@ -35,7 +32,7 @@ set_output_delay -min -clock SDRAM_CLK -0.9ns [get_ports {SDRAM_D* SDRAM_A* SDRA # Decouple different clock groups (to simplify routing) set_clock_groups -asynchronous \ - -group [get_clocks { *|pll|pll_inst|altera_pll_i|general[*].gpll~PLL_OUTPUT_COUNTER|divclk ZCLK}] \ + -group [get_clocks { *|pll|pll_inst|altera_pll_i|general[*].gpll~PLL_OUTPUT_COUNTER|divclk}] \ -group [get_clocks { pll_hdmi|pll_hdmi_inst|altera_pll_i|cyclonev_pll|counter[0].output_counter|divclk VID_CLK}] \ -group [get_clocks { *|h2f_user0_clk}] \ -group [get_clocks { FPGA_CLK1_50 FPGA_CLK2_50 FPGA_CLK3_50}]