From 861cd1e00d0cee6623a6e875a7d5a84e2c6d803c Mon Sep 17 00:00:00 2001 From: Matthias Blankertz Date: Fri, 8 Mar 2013 21:43:43 +0100 Subject: [PATCH] - Integrated DDR controller with VGA and cache controller - Debugged the above --- Makefile | 2 +- src/toplevel.vhd | 158 ++++---- src/vga.vhd | 14 +- src/vga_pixelreader.vhd | 19 +- src/wb_ddr_ctrl.vhd | 10 +- src/wb_ddr_ctrl_wb.vhd | 12 +- src/wb_ddr_ctrl_wb_sc.vhd | 274 ++++++++++---- src/wb_ddr_ctrl_wb_sc_fe.vhd | 118 +++--- src/wb_ddr_ctrl_wb_sc_fe_fsm.vhd | 39 +- src/wb_ddr_ctrl_wb_sc_fe_ram.vhd | 143 ++++++++ tb/toplevel_tb.vhd | 21 +- tb/vga_tb.vhd | 28 +- tb/wb_ddr_ctrl_wb_sc_fe_tb.vhd | 41 ++- tb/wb_ddr_ctrl_wb_sc_tb.vhd | 316 ++++++++++++++++ wb_ddr_ctrl_wb_sc_tb.wcfg | 611 +++++++++++++++++++++++++++++++ 15 files changed, 1511 insertions(+), 295 deletions(-) create mode 100644 src/wb_ddr_ctrl_wb_sc_fe_ram.vhd create mode 100644 tb/wb_ddr_ctrl_wb_sc_tb.vhd create mode 100644 wb_ddr_ctrl_wb_sc_tb.wcfg diff --git a/Makefile b/Makefile index d283b60..6f47837 100755 --- a/Makefile +++ b/Makefile @@ -29,7 +29,7 @@ src/wb_interconnect.vhd \ src/wb_rom.vhd src/wb_ram.vhd \ src/clk_reset.vhd src/wb_ddr_ctrl.vhd src/wb_ddr_ctrl_ddrwrap.vhd \ src/wb_ddr_ctrl_wb.vhd src/wb_ddr_ctrl_wb_dc_fsm.vhd src/wb_ddr_ctrl_wb_dc.vhd \ -src/wb_ddr_ctrl_wb_sc_fe_fsm.vhd src/wb_ddr_ctrl_wb_sc_fe.vhd \ +src/wb_ddr_ctrl_wb_sc_fe_ram.vhd src/wb_ddr_ctrl_wb_sc_fe_fsm.vhd src/wb_ddr_ctrl_wb_sc_fe.vhd \ src/wb_ddr_ctrl_wb_sc.vhd src/vga_syncgen.vhd src/vga_pixelgen.vhd \ src/vga_pixelreader.vhd src/vga.vhd \ src/toplevel.vhd diff --git a/src/toplevel.vhd b/src/toplevel.vhd index 37cb74f..da35e44 100755 --- a/src/toplevel.vhd +++ b/src/toplevel.vhd @@ -34,40 +34,43 @@ use UNISIM.VComponents.all; use work.intercon_package.all; entity toplevel is - Port ( - -- global signals - clkin_50MHz : IN std_ulogic; - clkin_133MHz : IN std_ulogic; - reset : IN std_ulogic; - - -- VGA port - vga_r, vga_g, vga_b : OUT std_ulogic_vector(3 downto 0); - vga_vsync, vga_hsync : OUT std_ulogic; - - -- spi flash - dataflash_mosi, dataflash_sck, dataflash_ss, dataflash_wp, dataflash_rst : OUT std_ulogic; - dataflash_miso : IN std_ulogic; - - -- LEDs - led : OUT std_ulogic_vector(7 downto 0); - - -- DDR2 SDRAM - ddr2_dq : inout std_logic_vector(15 downto 0); - ddr2_a : out std_logic_vector(12 downto 0); - ddr2_ba : out std_logic_vector(1 downto 0); - ddr2_cke : out std_logic; - ddr2_cs_n : out std_logic; - ddr2_ras_n : out std_logic; - ddr2_cas_n : out std_logic; - ddr2_we_n : out std_logic; - ddr2_odt : out std_logic; - ddr2_dm : out std_logic_vector(1 downto 0); - rst_dqs_div_in : in std_logic; - rst_dqs_div_out : out std_logic; - ddr2_dqs : inout std_logic_vector(1 downto 0); - ddr2_dqs_n : inout std_logic_vector(1 downto 0); - ddr2_ck : out std_logic_vector(0 downto 0); - ddr2_ck_n : out std_logic_vector(0 downto 0) + generic ( + dontcare : std_logic := '-' + ); + Port ( + -- global signals + clkin_50MHz : IN std_ulogic; + clkin_133MHz : IN std_ulogic; + reset : IN std_ulogic; + + -- VGA port + vga_r, vga_g, vga_b : OUT std_logic_vector(3 downto 0); + vga_vsync, vga_hsync : OUT std_logic; + + -- spi flash + dataflash_mosi, dataflash_sck, dataflash_ss, dataflash_wp, dataflash_rst : OUT std_ulogic; + dataflash_miso : IN std_ulogic; + + -- LEDs + led : OUT std_ulogic_vector(7 downto 0); + + -- DDR2 SDRAM + ddr2_dq : inout std_logic_vector(15 downto 0); + ddr2_a : out std_logic_vector(12 downto 0); + ddr2_ba : out std_logic_vector(1 downto 0); + ddr2_cke : out std_logic; + ddr2_cs_n : out std_logic; + ddr2_ras_n : out std_logic; + ddr2_cas_n : out std_logic; + ddr2_we_n : out std_logic; + ddr2_odt : out std_logic; + ddr2_dm : out std_logic_vector(1 downto 0); + rst_dqs_div_in : in std_logic; + rst_dqs_div_out : out std_logic; + ddr2_dqs : inout std_logic_vector(1 downto 0); + ddr2_dqs_n : inout std_logic_vector(1 downto 0); + ddr2_ck : out std_logic_vector(0 downto 0); + ddr2_ck_n : out std_logic_vector(0 downto 0) ); end toplevel; @@ -76,10 +79,11 @@ architecture Mixed of toplevel is Generic ( reset_dcm_on_ext_reset : BOOLEAN := false ); - Port ( clkIn50 : in STD_ULOGIC; - sysClk50 : out STD_ULOGIC; - rstIn : in STD_ULOGIC; - sysRst50 : out STD_ULOGIC); + Port ( clkIn50 : in STD_LOGIC; + sysClk50 : out STD_LOGIC; + sysClk25 : out std_logic; + rstIn : in STD_LOGIC; + sysRst50 : out STD_LOGIC); end component; component wb_ddr_ctrl is Port ( @@ -109,7 +113,15 @@ architecture Mixed of toplevel is clk_i : in std_ulogic; rst_i : in std_ulogic; wbs_i : in sdram_ctrl_wbs_i_type; - wbs_o : out sdram_ctrl_wbs_o_type + wbs_o : out sdram_ctrl_wbs_o_type; + wbs_cc_i : in sdram_ctrl_cc_wbs_i_type; + wbs_cc_o : out sdram_ctrl_cc_wbs_o_type; + + -- Direct memctrl access for VGA + vga_mem_rdrq : in std_logic; + vga_mem_adr : in std_logic_vector(19 downto 0); + vga_mem_ack : out std_logic; + vga_mem_dat_i : out std_logic_vector(63 downto 0) ); end component; @@ -139,7 +151,7 @@ architecture Mixed of toplevel is mem_rdrq : out std_logic; mem_adr : out std_logic_vector(19 downto 0); mem_ack : in std_logic; - mem_dat_i : in std_logic_vector(31 downto 0); + mem_dat_i : in std_logic_vector(63 downto 0); red : out std_logic_vector(3 downto 0); green : out std_logic_vector(3 downto 0); blue : out std_logic_vector(3 downto 0); @@ -172,24 +184,24 @@ architecture Mixed of toplevel is component intercon port ( - vga_wbm_i : out vga_wbm_i_type; - vga_wbm_o : in vga_wbm_o_type; + dummy_wbm_o : in dummy_wbm_o_type; + cpu_wbm_i : out cpu_wbm_i_type; cpu_wbm_o : in cpu_wbm_o_type; - ram_wbs_i : in ram_wbs_i_type; + ram_wbs_i : out ram_wbs_i_type; ram_wbs_o : in ram_wbs_o_type; - rom_wbs_i : in rom_wbs_i_type; + rom_wbs_i : out rom_wbs_i_type; rom_wbs_o : in rom_wbs_o_type; sdram_ctrl_wbs_i : out sdram_ctrl_wbs_i_type; sdram_ctrl_wbs_o : in sdram_ctrl_wbs_o_type; + sdram_ctrl_cc_wbs_i : out sdram_ctrl_cc_wbs_i_type; + sdram_ctrl_cc_wbs_o : in sdram_ctrl_cc_wbs_o_type; clk : in std_logic; reset : in std_logic); end component; signal sysClk, sysRst, vgaClk : std_logic; -signal vga_wbm_i : vga_wbm_i_type; -signal vga_wbm_o : vga_wbm_o_type; signal cpu_wbm_o : cpu_wbm_o_type; signal cpu_wbm_i : cpu_wbm_i_type; signal ram_wbs_o : ram_wbs_o_type; @@ -198,11 +210,13 @@ signal rom_wbs_o : rom_wbs_o_type; signal rom_wbs_i : rom_wbs_i_type; signal sdram_ctrl_wbs_i : sdram_ctrl_wbs_i_type; signal sdram_ctrl_wbs_o : sdram_ctrl_wbs_o_type; +signal sdram_ctrl_cc_wbs_i : sdram_ctrl_cc_wbs_i_type; +signal sdram_ctrl_cc_wbs_o : sdram_ctrl_cc_wbs_o_type; signal vga_mem_rdrq : std_logic; signal vga_mem_adr : std_logic_vector(19 downto 0); signal vga_mem_ack : std_logic; -signal vga_mem_dat_i : std_logic_vector(31 downto 0); +signal vga_mem_dat_i : std_logic_vector(63 downto 0); signal enable_vga : std_logic; @@ -212,7 +226,7 @@ sys_clk_rst : clk_reset clkIn50 => clkin_50MHz, rstIn => reset, sysClk50 => sysClk, - sysClk15 => vgaClk, + sysClk25 => vgaClk, sysRst50 => sysRst ); @@ -243,32 +257,39 @@ ddr_ctrl0 : wb_ddr_ctrl clk_i => sysClk, rst_i => sysRst, wbs_i => sdram_ctrl_wbs_i, - wbs_o => sdram_ctrl_wbs_o + wbs_o => sdram_ctrl_wbs_o, + wbs_cc_i => sdram_ctrl_cc_wbs_i, + wbs_cc_o => sdram_ctrl_cc_wbs_o, + + vga_mem_rdrq => vga_mem_rdrq, + vga_mem_adr => vga_mem_adr, + vga_mem_ack => vga_mem_ack, + vga_mem_dat_i => vga_mem_dat_i ); vga_1: vga generic map ( - h_total_pixels => h_total_pixels, - h_front_porch => h_front_porch, - h_back_porch => h_back_porch, - h_sync_pulse => h_sync_pulse, - h_sync_pos => h_sync_pos, - h_active_pixels => h_active_pixels, - v_total_lines => v_total_lines, - v_front_porch => v_front_porch, - v_back_porch => v_back_porch, - v_sync_pulse => v_sync_pulse, - v_sync_pos => v_sync_pos, - v_active_lines => v_active_lines, - framebuffer0_base => framebuffer0_base, - burst_length => burst_length, - burst_length_ln2 => burst_length_ln2, - addr_width => addr_width, + h_total_pixels => 800, + h_front_porch => 16, + h_back_porch => 48, + h_sync_pulse => 96, + h_sync_pos => false, + h_active_pixels => 640, + v_total_lines => 525, + v_front_porch => 10, + v_back_porch => 33, + v_sync_pulse => 2, + v_sync_pos => false, + v_active_lines => 480, + framebuffer0_base => 0, + burst_length => 8, + burst_length_ln2 => 3, + addr_width => 24, dontcare => dontcare) port map ( clk_in => sysClk, clk_vga => vgaClk, - rst => rst, + rst => sysRst, mem_rdrq => vga_mem_rdrq, mem_adr => vga_mem_adr, @@ -303,8 +324,6 @@ cpu_system_inst: cpu_system intercon_1: intercon port map ( - vga_wbm_i => vga_wbm_i, - vga_wbm_o => vga_wbm_o, cpu_wbm_i => cpu_wbm_i, cpu_wbm_o => cpu_wbm_o, rom_wbs_i => rom_wbs_i, @@ -313,6 +332,9 @@ intercon_1: intercon ram_wbs_o => ram_wbs_o, sdram_ctrl_wbs_i => sdram_ctrl_wbs_i, sdram_ctrl_wbs_o => sdram_ctrl_wbs_o, + sdram_ctrl_cc_wbs_i => sdram_ctrl_cc_wbs_i, + sdram_ctrl_cc_wbs_o => sdram_ctrl_cc_wbs_o, + dummy_wbm_o => ("----", (others => '-'), "--", "---", '0', '0'), clk => sysClk, reset => sysRst); diff --git a/src/vga.vhd b/src/vga.vhd index fa38046..ee60e3a 100644 --- a/src/vga.vhd +++ b/src/vga.vhd @@ -50,8 +50,8 @@ entity vga is v_active_lines : integer := 480; framebuffer0_base : integer := 0; - burst_length : integer := 16; - burst_length_ln2 : integer := 4; + burst_length : integer := 8; + burst_length_ln2 : integer := 3; addr_width : integer := 24; dontcare : std_logic := '-' ); @@ -64,7 +64,7 @@ entity vga is mem_rdrq : out std_logic; mem_adr : out std_logic_vector(19 downto 0); mem_ack : in std_logic; - mem_dat_i : in std_logic_vector(31 downto 0); + mem_dat_i : in std_logic_vector(63 downto 0); -- to vga red : out std_logic_vector(3 downto 0); @@ -90,7 +90,7 @@ architecture Structural of vga is clk : in std_logic; rst : in std_logic; - pixeldata : out std_logic_vector(31 downto 0); + pixeldata : out std_logic_vector(63 downto 0); fifo_write : out std_logic; fifo_full16 : in std_logic; fifo_rst : out std_logic; @@ -99,7 +99,7 @@ architecture Structural of vga is mem_rdrq : out std_logic; mem_adr : out std_logic_vector(19 downto 0); mem_ack : in std_logic; - mem_dat_i : in std_logic_vector(31 downto 0)); + mem_dat_i : in std_logic_vector(63 downto 0)); end component; component vga_pixeldata_fifo @@ -107,7 +107,7 @@ architecture Structural of vga is rst : IN STD_LOGIC; wr_clk : IN STD_LOGIC; rd_clk : IN STD_LOGIC; - din : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + din : IN STD_LOGIC_VECTOR(63 DOWNTO 0); wr_en : IN STD_LOGIC; rd_en : IN STD_LOGIC; dout : OUT STD_LOGIC_VECTOR(15 DOWNTO 0); @@ -148,7 +148,7 @@ architecture Structural of vga is blue : out std_logic_vector(3 downto 0)); end component; - signal in_pixeldata : std_logic_vector(31 downto 0); + signal in_pixeldata : std_logic_vector(63 downto 0); signal out_pixeldata : std_logic_vector(15 downto 0); signal fifo_write, fifo_read, fifo_empty, fifo_full16, fifo_rst : std_logic; diff --git a/src/vga_pixelreader.vhd b/src/vga_pixelreader.vhd index 73d6121..5025dd2 100644 --- a/src/vga_pixelreader.vhd +++ b/src/vga_pixelreader.vhd @@ -36,9 +36,9 @@ use work.intercon_package.all; entity vga_pixelreader is generic ( framebuffer0_base : integer := 0; - burst_length : integer := 16; - burst_length_ln2 : integer := 4; - addr_width : integer := 24; + burst_length : integer := 8; + burst_length_ln2 : integer := 3; + addr_width : integer := 23; dontcare : std_logic := '-'; h_active_pixels : integer := 640; v_active_lines : integer := 480 @@ -47,7 +47,7 @@ entity vga_pixelreader is clk : in std_logic; rst : in std_logic; - pixeldata : out std_logic_vector(31 downto 0); + pixeldata : out std_logic_vector(63 downto 0); fifo_write : out std_logic; fifo_full16 : in std_logic; fifo_rst : out std_logic; @@ -56,7 +56,7 @@ entity vga_pixelreader is mem_rdrq : out std_logic; mem_adr : out std_logic_vector(19 downto 0); mem_ack : in std_logic; - mem_dat_i : in std_logic_vector(31 downto 0) + mem_dat_i : in std_logic_vector(63 downto 0) ); end vga_pixelreader; @@ -67,12 +67,13 @@ architecture Behavioral of vga_pixelreader is signal state : states := S_INIT; - signal addr_ctr : natural range 0 to (pixels/(2*burst_length))-1 := 0; + signal addr_ctr : natural range 0 to (pixels/(4*burst_length))-1 := 0; signal burst_ctr : natural range 0 to burst_length-1 := 0; begin fifo_write <= mem_ack; -pixeldata <= mem_dat_i; +pixeldata <= mem_dat_i(15 downto 0) & mem_dat_i(31 downto 16) & + mem_dat_i(47 downto 32) & mem_dat_i(63 downto 48); pixelreader : process(clk) begin @@ -90,7 +91,7 @@ pixelreader : process(clk) when S_IDLE => if fifo_full16 = '0' then -- space in fifo for a burst of data mem_rdrq <= '1'; - mem_adr <= std_logic_vector(to_unsigned(framebuffer0_base/(burst_length*4)+addr_ctr, mem_adr'length)); + mem_adr <= std_logic_vector(to_unsigned(framebuffer0_base/(burst_length*8)+addr_ctr, mem_adr'length)); burst_ctr <= 0; state <= S_READ; @@ -98,7 +99,7 @@ pixelreader : process(clk) when S_READ => if mem_ack = '1' then if burst_ctr = burst_length-1 then - if addr_ctr = (pixels/(2*burst_length))-1 then + if addr_ctr = (pixels/(4*burst_length))-1 then addr_ctr <= 0; state <= S_WAIT_VSYNC; else diff --git a/src/wb_ddr_ctrl.vhd b/src/wb_ddr_ctrl.vhd index 8b8aab2..206e37b 100755 --- a/src/wb_ddr_ctrl.vhd +++ b/src/wb_ddr_ctrl.vhd @@ -64,12 +64,14 @@ entity wb_ddr_ctrl is rst_i : in std_ulogic; wbs_i : in sdram_ctrl_wbs_i_type; wbs_o : out sdram_ctrl_wbs_o_type; + wbs_cc_i : in sdram_ctrl_cc_wbs_i_type; + wbs_cc_o : out sdram_ctrl_cc_wbs_o_type; -- Direct memctrl access for VGA vga_mem_rdrq : in std_logic; vga_mem_adr : in std_logic_vector(19 downto 0); vga_mem_ack : out std_logic; - vga_mem_dat_i : out std_logic_vector(31 downto 0) + vga_mem_dat_i : out std_logic_vector(63 downto 0) ); end wb_ddr_ctrl; @@ -144,12 +146,14 @@ component wb_ddr_ctrl_wb is rst_i : in std_ulogic; wbs_i : in sdram_ctrl_wbs_i_type; wbs_o : out sdram_ctrl_wbs_o_type; + wbs_cc_i : in sdram_ctrl_cc_wbs_i_type; + wbs_cc_o : out sdram_ctrl_cc_wbs_o_type; -- Direct memctrl access for VGA vga_mem_rdrq : in std_logic; vga_mem_adr : in std_logic_vector(19 downto 0); vga_mem_ack : out std_logic; - vga_mem_dat_i : out std_logic_vector(31 downto 0) + vga_mem_dat_i : out std_logic_vector(63 downto 0) ); end component; @@ -227,6 +231,8 @@ wb_0 : wb_ddr_ctrl_wb wbs_i => wbs_i, wbs_o => wbs_o, + wbs_cc_i => wbs_cc_i, + wbs_cc_o => wbs_cc_o, vga_mem_rdrq => vga_mem_rdrq, vga_mem_adr => vga_mem_adr, diff --git a/src/wb_ddr_ctrl_wb.vhd b/src/wb_ddr_ctrl_wb.vhd index 528bc7b..0e83297 100755 --- a/src/wb_ddr_ctrl_wb.vhd +++ b/src/wb_ddr_ctrl_wb.vhd @@ -58,12 +58,14 @@ entity wb_ddr_ctrl_wb is rst_i : in std_ulogic; wbs_i : in sdram_ctrl_wbs_i_type; wbs_o : out sdram_ctrl_wbs_o_type; + wbs_cc_i : in sdram_ctrl_cc_wbs_i_type; + wbs_cc_o : out sdram_ctrl_cc_wbs_o_type; -- Direct memctrl access for VGA vga_mem_rdrq : in std_logic; vga_mem_adr : in std_logic_vector(19 downto 0); vga_mem_ack : out std_logic; - vga_mem_dat_i : out std_logic_vector(31 downto 0) + vga_mem_dat_i : out std_logic_vector(63 downto 0) ); end wb_ddr_ctrl_wb; @@ -101,12 +103,14 @@ component wb_ddr_ctrl_wb_sc is rst_i : in std_ulogic; wbs_i : in sdram_ctrl_wbs_i_type; wbs_o : out sdram_ctrl_wbs_o_type; + wbs_cc_i : in sdram_ctrl_cc_wbs_i_type; + wbs_cc_o : out sdram_ctrl_cc_wbs_o_type; -- Direct memctrl access for VGA vga_mem_rdrq : in std_logic; vga_mem_adr : in std_logic_vector(19 downto 0); vga_mem_ack : out std_logic; - vga_mem_dat_i : out std_logic_vector(31 downto 0); + vga_mem_dat_i : out std_logic_vector(63 downto 0); -- To/from ddr clock domain ddr_din : out std_logic_vector(63 downto 0); @@ -177,8 +181,10 @@ system_cd_inst : wb_ddr_ctrl_wb_sc -- Wishbone slave clk_i => clk_i, rst_i => rst_i, - wbs_i => wbs_i, + wbs_i => wbs_i, wbs_o => wbs_o, + wbs_cc_i => wbs_cc_i, + wbs_cc_o => wbs_cc_o, vga_mem_rdrq => vga_mem_rdrq, vga_mem_adr => vga_mem_adr, diff --git a/src/wb_ddr_ctrl_wb_sc.vhd b/src/wb_ddr_ctrl_wb_sc.vhd index 9e92501..97335f7 100755 --- a/src/wb_ddr_ctrl_wb_sc.vhd +++ b/src/wb_ddr_ctrl_wb_sc.vhd @@ -35,7 +35,8 @@ use work.intercon_package.all; entity wb_ddr_ctrl_wb_sc is generic ( - burst_length : integer := 16; + burst_length : integer := 8; + burst_length_ln2 : integer := 3; dontcare : std_logic := '-' ); port ( @@ -47,7 +48,7 @@ entity wb_ddr_ctrl_wb_sc is wbs_cc_i : in sdram_ctrl_cc_wbs_i_type; wbs_cc_o : out sdram_ctrl_cc_wbs_o_type; - -- Direct memctrl access for VGA + -- Direct memctrl access for VGA vga_mem_rdrq : in std_logic; vga_mem_adr : in std_logic_vector(19 downto 0); vga_mem_ack : out std_logic; @@ -84,29 +85,62 @@ architecture Behavioral of wb_ddr_ctrl_wb_sc is wbs_o : out sdram_ctrl_wbs_o_type; wbs_cc_i : in sdram_ctrl_cc_wbs_i_type; wbs_cc_o : out sdram_ctrl_cc_wbs_o_type; - mem_adr : out std_logic_vector(addr_width-line_size_ln2-1 downto 0); + mem_adr : out std_logic_vector(19 downto 0); mem_rdrq : out std_logic; mem_wrrq : out std_logic; - mem_dat_o : out std_logic_vector(31 downto 0); + mem_dat_o : out std_logic_vector(63 downto 0); mem_ack : in std_logic; - mem_dat_i : in std_logic_vector(31 downto 0)); + mem_dat_i : in std_logic_vector(63 downto 0)); end component; - type states is (S_IDLE); - signal state : states := S_IDLE; - - signal cfe_mem_adr : std_logic_vector(addr_width-line_size_ln2-1 downto 0); + signal cfe_mem_adr : std_logic_vector(19 downto 0); signal cfe_mem_rdrq : std_logic; signal cfe_mem_wrrq : std_logic; signal cfe_mem_dat_o : std_logic_vector(63 downto 0); signal cfe_mem_ack : std_logic; - signal cfe_mem_dat_i : std_logic_vector(63 downto 0)); + signal cfe_mem_dat_i : std_logic_vector(63 downto 0); - signal vga_active, cfe_active, burst_ctr_inc, burst_ctr_rst : std_logic := '1'; - signal in_ctr, out_ctr : unsigned(2 downto 0) := to_unsigned(0, 3); - signal in_complete, out_complete, rq_complete : std_logic := '1'; + signal vga_rdrq_reg : std_logic := '0'; + signal vga_adr_reg : std_logic_vector(19 downto 0) := (others => dontcare); + signal vga_rq_complete : std_logic := '0'; + + signal cfe_rdrq_reg : std_logic := '0'; + signal cfe_wrrq_reg : std_logic := '0'; + signal cfe_adr_reg : std_logic_vector(19 downto 0) := (others => dontcare); + signal cfe_rq_complete : std_logic := '0'; + + signal dout_data_valid : std_logic := '0'; + + type bus_owner_t is (B_IDLE, B_VGA, B_CFE); + signal bus_owner, bus_owner_reg : bus_owner_t := B_IDLE; + + signal out_ctr, in_ctr : integer range 0 to burst_length-1 := 0; + signal out_complete, in_complete : std_logic := '0'; + + signal in_read, in_write : std_logic := '0'; + + constant write_delay : integer := 2; + type ddr_adr_dly_a is array(write_delay-1 downto 0) of std_logic_vector(22 downto 0); + signal ddr_adr_int : std_logic_vector(22 downto 0) := (others => dontcare); + signal ddr_adr_dly : ddr_adr_dly_a := (others => (others => dontcare)); + signal ddr_we_int : std_logic := dontcare; + signal ddr_we_dly : std_logic_vector(write_delay-1 downto 0) := (others => dontcare); + signal fifo_to_ddr_write_int : std_logic := '0'; + signal fifo_to_ddr_write_dly : std_logic_vector(write_delay-1 downto 0) := (others => '0'); + signal out_complete_dly : std_logic_vector(write_delay-1 downto 0) := (others => '0'); + + signal fifo_to_ddr_full_last : std_logic := '1'; begin wb_ddr_ctrl_wb_sc_fe_1: wb_ddr_ctrl_wb_sc_fe + generic map ( + line_size => burst_length, + lines => 64, + assoc => 2, + line_size_ln2 => burst_length_ln2, + lines_ln2 => 6, + assoc_ln2 => 1, + addr_width => 23 + ) port map ( clk_i => clk_i, rst_i => rst_i, @@ -121,84 +155,164 @@ begin mem_ack => cfe_mem_ack, mem_dat_i => cfe_mem_dat_i); - cfe_mem_dat_i <= ddr_din; - vga_mem_dat_i <= ddr_din; - - ddr_adr(22 downto 3) <= vga_mem_adr when vga_active = '1' else - cfe_mem_adr when cfe_active = '1' else - (others => dontcare); - ddr_adr(2 downto 0) <= std_logic_vector(burst_ctr); - - ddr_we <= '0' when vga_active = '1' else - dontcare; - - fifo_to_ddr_write <= '1' when out_complete = '0' and fifo_to_ddr_full = '0' and - state /= S_IDLE else - '0'; - - mem_if : process(clk_i) - begin - if rising_edge(clk_i) then - fifo_to_ddr_write <= '0'; - - case state is - when S_IDLE => - if fifo_to_ddr_full = '0' then - if vga_mem_rdrq = '1' then - fifo_to_ddr_write <= '1'; - state <= S_VGA_RDRQ; - elsif cfe_mem_rdrq = '1' then - elsif cfe_mem_wrrq = '1' then - end if; - end if; - when S_VGA_RDRQ_SEND => - if rq_complete = '1' then - state <= S_IDLE; - end if; - end case; - end if; - end process mem_if; - - vga_active <= '1' when state = S_VGA_RDRQ else - '0'; - cfe_active <= '1' when state = S_CFE_RDRQ or state = S_CFE_WRRQ else - '0'; - - out_ctr_in <= '1' when fifo_to_ddr_write = '1' and out_complete = '0' else - '0'; - - out_ctr_rst <= '1' when fifo_to_ddr_full = '0' and (vga_mem_rdrq = '1' or cfe_mem_rdrq = '1' or - cfe_mem_rdrq = '1') and state = S_IDLE else + vga_mem_dat_i <= ddr_dout; + vga_mem_ack <= dout_data_valid when bus_owner_reg = B_VGA else + '0'; + cfe_mem_dat_i <= ddr_dout; + cfe_mem_ack <= dout_data_valid when bus_owner_reg = B_CFE and cfe_rdrq_reg = '1' else + not fifo_to_ddr_full when bus_owner_reg = B_CFE and cfe_wrrq_reg = '1' else '0'; - rq_complete <= in_complete and out_complete; + fifo_from_ddr_read <= not fifo_from_ddr_empty; + + ddr_be <= (others => '1'); + ddr_din <= cfe_mem_dat_o; + ddr_adr_int(22 downto 3) <= vga_adr_reg when bus_owner = B_VGA else + cfe_adr_reg when bus_owner = B_CFE else + (others => dontcare); + ddr_adr_int(2 downto 0) <= std_logic_vector(to_unsigned(out_ctr, 3)); + ddr_we_int <= '1' when bus_owner = B_CFE and cfe_wrrq_reg = '1' else + '0'; + fifo_to_ddr_write_int <= '1' when fifo_to_ddr_full = '0' and bus_owner /= B_IDLE and + out_complete = '0' and (vga_rdrq_reg = '1' or + cfe_rdrq_reg = '1') else + '1' when fifo_to_ddr_full = '0' and bus_owner = B_CFE and + cfe_wrrq_reg = '1' else + '0'; + + ddr_adr <= ddr_adr_int when in_read = '1' else + ddr_adr_dly(write_delay-1) when in_write = '1' else + (others => dontcare); + ddr_we <= ddr_we_int when in_read = '1' else + ddr_we_dly(write_delay-1) when in_write = '1' else + dontcare; + fifo_to_ddr_write <= fifo_to_ddr_write_int when in_read = '1' else + fifo_to_ddr_write_dly(write_delay-1) and not fifo_to_ddr_full when in_write = '1' else + '0'; + + write_dly : process(clk_i) + begin + if rising_edge(clk_i) then + if in_write = '1' then + if fifo_to_ddr_full = '0' then + if write_delay > 1 then + ddr_adr_dly(write_delay-1 downto 1) <= ddr_adr_dly(write_delay-2 downto 0); + ddr_we_dly(write_delay-1 downto 1) <= ddr_we_dly(write_delay-2 downto 0); + fifo_to_ddr_write_dly(write_delay-1 downto 1) <= fifo_to_ddr_write_dly(write_delay-2 downto 0); + out_complete_dly(write_delay-1 downto 1) <= out_complete_dly(write_delay-2 downto 0); + end if; + ddr_adr_dly(0) <= ddr_adr_int; + ddr_we_dly(0) <= ddr_we_int; + fifo_to_ddr_write_dly(0) <= fifo_to_ddr_write_int; + out_complete_dly(0) <= out_complete; + end if; + else + fifo_to_ddr_write_dly <= (others => '0'); + end if; + end if; + end process write_dly; + + ddr_dout_p : process(clk_i) + begin + if rising_edge(clk_i) then + dout_data_valid <= not fifo_from_ddr_empty; + end if; + end process ddr_dout_p; + + vga_rq_regs : process(clk_i) + begin + if rising_edge(clk_i) then + if vga_mem_rdrq = '1' then + vga_rdrq_reg <= '1'; + vga_adr_reg <= vga_mem_adr; + elsif vga_rq_complete = '1' then + vga_rdrq_reg <= '0'; + vga_adr_reg <= (others => dontcare); + end if; + end if; + end process vga_rq_regs; + + cfe_rq_regs : process(clk_i) + begin + if rising_edge(clk_i) then + if cfe_mem_rdrq = '1' then + cfe_rdrq_reg <= '1'; + cfe_adr_reg <= cfe_mem_adr; + elsif cfe_mem_wrrq = '1' then + cfe_wrrq_reg <= '1'; + cfe_adr_reg <= cfe_mem_adr; + elsif cfe_rq_complete = '1' then + cfe_rdrq_reg <= '0'; + cfe_wrrq_reg <= '0'; + cfe_adr_reg <= (others => dontcare); + end if; + end if; + end process cfe_rq_regs; + + bus_owner <= B_VGA when bus_owner_reg = B_IDLE and vga_rdrq_reg = '1' else + B_CFE when bus_owner_reg = B_IDLE and (cfe_rdrq_reg = '1' or cfe_wrrq_reg = '1') else + B_IDLE when bus_owner_reg = B_VGA and vga_rq_complete = '1' else + B_IDLE when bus_owner_reg = B_CFE and cfe_rq_complete = '1' else + bus_owner_reg; + + bus_owner_p : process(clk_i) + begin + if rising_edge(clk_i) then + bus_owner_reg <= bus_owner; + end if; + end process bus_owner_p; + + fifo_to_ddr_full_ff : process(clk_i) + begin + if rising_edge(clk_i) then + fifo_to_ddr_full_last <= fifo_to_ddr_full; + end if; + end process fifo_to_ddr_full_ff; + + in_read <= '1' when bus_owner = B_VGA else + '1' when bus_owner = B_CFE and cfe_rdrq_reg = '1' else + '0'; + in_write <= '1' when bus_owner = B_CFE and cfe_wrrq_reg = '1' else + '0'; + + vga_rq_complete <= '1' when in_complete = '1' and out_complete = '1' and bus_owner_reg = B_VGA else + '0'; + cfe_rq_complete <= '1' when (in_complete = '1' and out_complete = '1' and + cfe_rdrq_reg = '1' and bus_owner_reg = B_CFE) else + '1' when (out_complete_dly(write_delay-1) = '1' and fifo_to_ddr_full_last = '0' and + cfe_wrrq_reg = '1' and bus_owner_reg = B_CFE) else + '0'; out_ctr_p : process(clk_i) begin if rising_edge(clk_i) then - if out_ctr_rst = '1' then - out_ctr <= to_unsigned(0, 3); - elsif out_ctr_inc = '1' then - out_ctr <= out_ctr + 1; - end if; - end if; - end process burst_ctr_p; - - out_complete_p : process(clk_i) - begin - if rising_edge(clk_i) then - if out_ctr_rst = '1' then + if (bus_owner /= B_IDLE and out_complete = '0' and fifo_to_ddr_full = '0') then + if out_ctr = burst_length-1 then + out_complete <= '1'; + else + out_ctr <= out_ctr + 1; + end if; + elsif vga_rq_complete = '1' or cfe_rq_complete = '1' then + out_ctr <= 0; out_complete <= '0'; - elsif fifo_to_ddr_write = '1' and out_ctr = 7 then - out_complete <= '1'; end if; end if; - end process out_complete_p; + end process out_ctr_p; - in_complete_p : process(clk_i) + in_ctr_p : process(clk_i) begin if rising_edge(clk_i) then - if out_ctr_rst = '1' then - + if bus_owner /= B_IDLE and in_complete = '0' and fifo_from_ddr_empty = '0' then + if in_ctr = burst_length-1 then + in_complete <= '1'; + else + in_ctr <= in_ctr + 1; + end if; + elsif vga_rq_complete = '1' or cfe_rq_complete = '1' then + in_ctr <= 0; + in_complete <= '0'; + end if; + end if; + end process in_ctr_p; end Behavioral; diff --git a/src/wb_ddr_ctrl_wb_sc_fe.vhd b/src/wb_ddr_ctrl_wb_sc_fe.vhd index f068366..c12669b 100644 --- a/src/wb_ddr_ctrl_wb_sc_fe.vhd +++ b/src/wb_ddr_ctrl_wb_sc_fe.vhd @@ -98,6 +98,7 @@ architecture Behavioral of wb_ddr_ctrl_wb_sc_fe is user_cc_req_inval : in std_logic; user_cc_read : in std_logic; adr_tag_eq_num_dirty : in std_logic; + mem_ack : in std_logic; ack_o : out std_logic; update_lru : out std_logic := '0'; set_dirty : out std_logic := '0'; @@ -111,6 +112,25 @@ architecture Behavioral of wb_ddr_ctrl_wb_sc_fe is user_cc_ack_o : out std_logic := '0'; user_cc : out std_logic := '0'); end component; + + component wb_ddr_ctrl_wb_sc_fe_ram + generic ( + lines : integer; + line_size : integer; + lines_ln2 : integer; + line_size_ln2 : integer + ); + port ( + clk_i : in std_logic; + + rd_addr : in unsigned(lines_ln2+line_size_ln2-1 downto 0); + rd_data : out std_logic_vector(63 downto 0); + + wr_addr : in unsigned(lines_ln2+line_size_ln2-1 downto 0); + wr_data : in std_logic_vector(63 downto 0); + bwe : in std_logic_vector(7 downto 0) + ); + end component; -- Derived parameters constant tag_width : integer := addr_width-line_size_ln2-(lines_ln2-assoc_ln2); @@ -129,9 +149,9 @@ architecture Behavioral of wb_ddr_ctrl_wb_sc_fe is signal cc_valid : cc_valid_a := (others => (others => '0')); signal cc_dirty : cc_dirty_a := (others => (others => '-')); attribute ram_style of cc_tag : signal is "block"; - attribute ram_style of cc_lru : signal is "block"; - attribute ram_style of cc_valid : signal is "block"; - attribute ram_style of cc_dirty : signal is "block"; + attribute ram_style of cc_lru : signal is "auto"; + attribute ram_style of cc_valid : signal is "auto"; + attribute ram_style of cc_dirty : signal is "auto"; signal cc_we : std_logic := '0'; signal cc_wr_addr, cc_rd_addr : unsigned(lines_ln2-assoc_ln2-1 downto 0) := (others => '-'); signal cc_tag_wr_data, cc_tag_rd_data : tag_t := (others => '-'); @@ -144,15 +164,11 @@ architecture Behavioral of wb_ddr_ctrl_wb_sc_fe is signal tags : tag_a := (others => (others => '-')); -- Cache data signals / memory - type cache_arr is array(lines*line_size-1 downto 0) of std_logic_vector(63 downto 0); - signal cache : cache_arr := (others => (others => '-')); - attribute ram_style of cache : signal is "block"; -- signal cache_we : std_logic := '0'; signal cache_wr_addr, cache_rd_addr : unsigned(lines_ln2+line_size_ln2-1 downto 0) := (others => '0'); signal cache_wr_data, cache_rd_data : std_logic_vector(63 downto 0) := (others => '-'); signal cache_bwe : std_logic_vector(7 downto 0) := (others => '-'); - signal cache_di7, cache_di6, cache_di5, cache_di4 : std_logic_vector(7 downto 0); - signal cache_di3, cache_di2, cache_di1, cache_di0 : std_logic_vector(7 downto 0); + -- Convenience variables for adr_i signal adr_index : unsigned(index_width-1 downto 0); @@ -173,16 +189,16 @@ architecture Behavioral of wb_ddr_ctrl_wb_sc_fe is -- control signals signal update_lru, set_dirty, set_valid, cache_write, cache_from_mem, eject_dirty : std_logic; signal set_invalid, cache_to_mem, user_cc, adr_tag_eq_num_dirty : std_logic; - signal mem_offset : unsigned(offset_width-1 downto 0); + signal mem_offset, mem_offset_dly : unsigned(offset_width-1 downto 0); signal mem_rdrq_int, mem_wrrq_int : std_logic; signal user_cc_req_flush, user_cc_req_inval, user_cc_read : std_logic; begin cache_rd_addr <= adr_index & adr_tag_eq_num & adr_offset when cache_to_mem = '0' else - adr_index & eject_num & mem_offset; + adr_index & eject_num & mem_offset when mem_ack = '1' else + adr_index & eject_num & mem_offset_dly; cache_wr_addr <= adr_index & adr_tag_eq_num & adr_offset when cache_from_mem = '0' else adr_index & eject_num & mem_offset; - --cache_we <= cache_write or (cache_from_mem and mem_ack); cache_wr_data <= wbs_i.dat_i & wbs_i.dat_i when cache_write = '1' else mem_dat_i when cache_from_mem = '1' else (others => '-'); @@ -191,66 +207,19 @@ begin "11111111" when cache_from_mem = '1' and mem_ack = '1' else "00000000"; - cache_din : process(cache_wr_data, cache_wr_addr, cache_bwe) - begin - if cache_bwe(7) = '1' then - cache_di7 <= cache_wr_data(63 downto 56); - else - cache_di7 <= cache(to_integer(cache_wr_addr))(63 downto 56); - end if; - - if cache_bwe(6) = '1' then - cache_di6 <= cache_wr_data(55 downto 48); - else - cache_di6 <= cache(to_integer(cache_wr_addr))(55 downto 48); - end if; - - if cache_bwe(5) = '1' then - cache_di5 <= cache_wr_data(47 downto 40); - else - cache_di5 <= cache(to_integer(cache_wr_addr))(47 downto 40); - end if; - - if cache_bwe(4) = '1' then - cache_di4 <= cache_wr_data(39 downto 32); - else - cache_di4 <= cache(to_integer(cache_wr_addr))(39 downto 32); - end if; - - if cache_bwe(3) = '1' then - cache_di3 <= cache_wr_data(31 downto 24); - else - cache_di3 <= cache(to_integer(cache_wr_addr))(31 downto 24); - end if; - - if cache_bwe(2) = '1' then - cache_di2 <= cache_wr_data(23 downto 16); - else - cache_di2 <= cache(to_integer(cache_wr_addr))(23 downto 16); - end if; - - if cache_bwe(1) = '1' then - cache_di1 <= cache_wr_data(15 downto 8); - else - cache_di1 <= cache(to_integer(cache_wr_addr))(15 downto 8); - end if; - - if cache_bwe(0) = '1' then - cache_di0 <= cache_wr_data(7 downto 0); - else - cache_di0 <= cache(to_integer(cache_wr_addr))(7 downto 0); - end if; - end process cache_din; - - -- Memory for cache data - cache_mem : process(clk_i) - begin - if rising_edge(clk_i) then - cache(to_integer(cache_wr_addr)) <= cache_di7 & cache_di6 & cache_di5 & cache_di4 & - cache_di3 & cache_di2 & cache_di1 & cache_di0; - cache_rd_data <= cache(to_integer(cache_rd_addr)); - end if; - end process cache_mem; + wb_ddr_ctrl_wb_sc_fe_ram_inst: wb_ddr_ctrl_wb_sc_fe_ram + generic map ( + lines => lines, + line_size => line_size, + lines_ln2 => lines_ln2, + line_size_ln2 => line_size_ln2) + port map ( + clk_i => clk_i, + rd_addr => cache_rd_addr, + rd_data => cache_rd_data, + wr_addr => cache_wr_addr, + wr_data => cache_wr_data, + bwe => cache_bwe); wbs_o.dat_o <= cache_rd_data(63 downto 32) when wbs_i.adr_i(2) = '1' else cache_rd_data(31 downto 0); @@ -307,7 +276,7 @@ begin end if; end process cc_mem; - assert addr_width = wbs_i.adr_i'high report "Invalid address width, check parameters" severity error; + assert addr_width = (wbs_i.adr_i'high - wbs_i.adr_i'low) report "Invalid address width, check parameters" severity error; adr_index <= unsigned(wbs_cc_i.dat_i(offset_width+index_width+2 downto offset_width+3)) when user_cc = '1' else unsigned(wbs_i.adr_i(offset_width+index_width+2 downto offset_width+3)) ; adr_offset <= unsigned(wbs_cc_i.dat_i(offset_width+2 downto 3)) when user_cc = '1' else @@ -367,8 +336,10 @@ begin if rising_edge(clk_i) then if mem_rdrq_int = '1' or mem_wrrq_int = '1' then mem_offset <= to_unsigned(0,line_size_ln2); + mem_offset_dly <= to_unsigned(0, line_size_ln2); elsif mem_ack = '1' then mem_offset <= mem_offset + 1; + mem_offset_dly <= mem_offset; end if; end if; end process mem_offset_ctr; @@ -390,11 +361,12 @@ begin we_i => wbs_i.we_i, adr_tag_eq => adr_tag_eq, eject_dirty => eject_dirty, - mem_offset => mem_offset, + mem_offset => mem_offset_dly, user_cc_req_flush => user_cc_req_flush, user_cc_req_inval => user_cc_req_inval, user_cc_read => user_cc_read, adr_tag_eq_num_dirty => adr_tag_eq_num_dirty, + mem_ack => mem_ack, ack_o => wbs_o.ack_o, update_lru => update_lru, set_dirty => set_dirty, diff --git a/src/wb_ddr_ctrl_wb_sc_fe_fsm.vhd b/src/wb_ddr_ctrl_wb_sc_fe_fsm.vhd index d05cf5b..dd2d193 100644 --- a/src/wb_ddr_ctrl_wb_sc_fe_fsm.vhd +++ b/src/wb_ddr_ctrl_wb_sc_fe_fsm.vhd @@ -58,6 +58,7 @@ entity wb_ddr_ctrl_wb_sc_fe_fsm is user_cc_req_flush : in std_logic; user_cc_req_inval : in std_logic; user_cc_read : in std_logic; + mem_ack : in std_logic; ack_o : out std_logic; update_lru : out std_logic := '0'; @@ -75,8 +76,8 @@ entity wb_ddr_ctrl_wb_sc_fe_fsm is end wb_ddr_ctrl_wb_sc_fe_fsm; architecture Behavioral of wb_ddr_ctrl_wb_sc_fe_fsm is - type states is (S_IDLE, S_WRITEBACK, S_FETCH, S_WAIT, S_WAIT_FETCH, - S_USER_CC_INIT, S_USER_WRITEBACK); + type states is (S_IDLE, S_WRITEBACK1, S_WRITEBACK2, S_FETCH1, S_FETCH2, S_WAIT, S_WAIT_FETCH, + S_USER_CC_INIT, S_USER_WRITEBACK1, S_USER_WRITEBACK2); signal state : states := S_IDLE; begin @@ -108,11 +109,11 @@ begin if eject_dirty = '1' then cache_to_mem <= '1'; mem_wrrq <= '1'; - state <= S_WRITEBACK; + state <= S_WRITEBACK1; else cache_from_mem <= '1'; mem_rdrq <= '1'; - state <= S_FETCH; + state <= S_FETCH1; end if; else -- hit @@ -128,11 +129,11 @@ begin if eject_dirty = '1' then cache_to_mem <= '1'; mem_wrrq <= '1'; - state <= S_WRITEBACK; + state <= S_WRITEBACK1; else cache_from_mem <= '1'; mem_rdrq <= '1'; - state <= S_FETCH; + state <= S_FETCH1; end if; else -- hit @@ -146,22 +147,28 @@ begin end if; when S_WAIT => state <= S_IDLE; - when S_FETCH => + when S_FETCH1 => + cache_from_mem <= '1'; + state <= S_FETCH2; + when S_FETCH2 => cache_from_mem <= '1'; if mem_offset = line_size-1 then set_valid <= '1'; state <= S_WAIT; end if; - when S_WRITEBACK => + when S_WRITEBACK1 => cache_to_mem <= '1'; - if mem_offset = line_size-1 then + state <= S_WRITEBACK2; + when S_WRITEBACK2 => + cache_to_mem <= '1'; + if mem_offset = line_size-1 and mem_ack = '1' then cache_to_mem <= '0'; state <= S_WAIT_FETCH; end if; when S_WAIT_FETCH => cache_from_mem <= '1'; mem_rdrq <= '1'; - state <= S_FETCH; + state <= S_FETCH1; when S_USER_CC_INIT => user_cc <= '1'; if user_cc_req_inval = '1' then @@ -174,7 +181,7 @@ begin -- line is dirty, flush first cache_to_mem <= '1'; mem_wrrq <= '1'; - state <= S_USER_WRITEBACK; + state <= S_USER_WRITEBACK1; else set_invalid <= '1'; user_cc_ack_o <= '1'; @@ -189,15 +196,19 @@ begin else cache_to_mem <= '1'; mem_wrrq <= '1'; - state <= S_USER_WRITEBACK; + state <= S_USER_WRITEBACK1; end if; else -- WTF? state <= S_WAIT; end if; - when S_USER_WRITEBACK => + when S_USER_WRITEBACK1 => user_cc <= '1'; cache_to_mem <= '1'; - if mem_offset = line_size-1 then + state <= S_USER_WRITEBACK2; + when S_USER_WRITEBACK2 => + user_cc <= '1'; + cache_to_mem <= '1'; + if mem_offset = line_size-1 and mem_ack = '1' then cache_to_mem <= '0'; if user_cc_req_inval = '1' then set_invalid <= '1'; diff --git a/src/wb_ddr_ctrl_wb_sc_fe_ram.vhd b/src/wb_ddr_ctrl_wb_sc_fe_ram.vhd new file mode 100644 index 0000000..6690ff0 --- /dev/null +++ b/src/wb_ddr_ctrl_wb_sc_fe_ram.vhd @@ -0,0 +1,143 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 11/06/2012 03:04:35 PM +-- Design Name: +-- Module Name: wb_ddr_ctrl_wb_sc_fe_ram - Behavioral +-- Project Name: +-- Target Devices: +-- Tool Versions: +-- Description: Memory controller - system clock domain - Cache front-end - +-- RAM +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; + +-- Uncomment the following library declaration if using +-- arithmetic functions with Signed or Unsigned values +use IEEE.NUMERIC_STD.ALL; + +-- Uncomment the following library declaration if instantiating +-- any Xilinx primitives in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity wb_ddr_ctrl_wb_sc_fe_ram is + + generic ( + lines : integer; + line_size : integer; + lines_ln2 : integer; + line_size_ln2 : integer); + + port ( + clk_i : in std_logic; + rd_addr : in unsigned(lines_ln2+line_size_ln2-1 downto 0); + rd_data : out std_logic_vector(63 downto 0); + wr_addr : in unsigned(lines_ln2+line_size_ln2-1 downto 0); + wr_data : in std_logic_vector(63 downto 0); + bwe : in std_logic_vector(7 downto 0)); + +end wb_ddr_ctrl_wb_sc_fe_ram; + +architecture Behavioral of wb_ddr_ctrl_wb_sc_fe_ram is + attribute ram_style : string; + + type cache_arr is array(lines*line_size-1 downto 0) of std_logic_vector(31 downto 0); + signal cache_hi, cache_lo : cache_arr := (others => (others => '-')); + attribute ram_style of cache_hi : signal is "block"; + attribute ram_style of cache_lo : signal is "block"; + + signal di7, di6, di5, di4, di3, di2, di1, di0 : std_logic_vector(7 downto 0); + + signal wr_data_hi, wr_data_lo, rd_data_hi, rd_data_lo : std_logic_vector(31 downto 0); + signal bwe_hi, bwe_lo : std_logic_vector(3 downto 0); + +begin + wr_data_hi <= wr_data(63 downto 32); + wr_data_lo <= wr_data(31 downto 0); + rd_data <= rd_data_hi & rd_data_lo; + bwe_hi <= bwe(7 downto 4); + bwe_lo <= bwe(3 downto 0); + + cache_hi_din : process(wr_data_hi, wr_addr, bwe_hi) + begin + if bwe_hi(3) = '1' then + di7 <= wr_data_hi(31 downto 24); + else + di7 <= cache_hi(to_integer(wr_addr))(31 downto 24); + end if; + + if bwe_hi(2) = '1' then + di6 <= wr_data_hi(23 downto 16); + else + di6 <= cache_hi(to_integer(wr_addr))(23 downto 16); + end if; + + if bwe_hi(1) = '1' then + di5 <= wr_data_hi(15 downto 8); + else + di5 <= cache_hi(to_integer(wr_addr))(15 downto 8); + end if; + + if bwe_hi(0) = '1' then + di4 <= wr_data_hi(7 downto 0); + else + di4 <= cache_hi(to_integer(wr_addr))(7 downto 0); + end if; + end process cache_hi_din; + + cache_lo_din : process(wr_data_lo, wr_addr, bwe_lo) + begin + if bwe_lo(3) = '1' then + di3 <= wr_data_lo(31 downto 24); + else + di3 <= cache_lo(to_integer(wr_addr))(31 downto 24); + end if; + + if bwe_lo(2) = '1' then + di2 <= wr_data_lo(23 downto 16); + else + di2 <= cache_lo(to_integer(wr_addr))(23 downto 16); + end if; + + if bwe_lo(1) = '1' then + di1 <= wr_data_lo(15 downto 8); + else + di1 <= cache_lo(to_integer(wr_addr))(15 downto 8); + end if; + + if bwe_lo(0) = '1' then + di0 <= wr_data_lo(7 downto 0); + else + di0 <= cache_lo(to_integer(wr_addr))(7 downto 0); + end if; + end process cache_lo_din; + + -- Memory for cache data + cache_mem_hi : process(clk_i) + begin + if rising_edge(clk_i) then + cache_hi(to_integer(wr_addr)) <= di7 & di6 & di5 & di4; + rd_data_hi <= cache_hi(to_integer(rd_addr)); + end if; + end process cache_mem_hi; + + cache_mem_lo : process(clk_i) + begin + if rising_edge(clk_i) then + cache_lo(to_integer(wr_addr)) <= di3 & di2 & di1 & di0; + rd_data_lo <= cache_lo(to_integer(rd_addr)); + end if; + end process cache_mem_lo; +end Behavioral; diff --git a/tb/toplevel_tb.vhd b/tb/toplevel_tb.vhd index eb71c41..d57c7a8 100644 --- a/tb/toplevel_tb.vhd +++ b/tb/toplevel_tb.vhd @@ -6,7 +6,7 @@ -- Author : -- Company : -- Created : 2013-03-02 --- Last update: 2013-03-02 +-- Last update: 2013-03-08 -- Platform : -- Standard : VHDL'87 ------------------------------------------------------------------------------- @@ -38,7 +38,7 @@ architecture testbench of toplevel_tb is clkin_50MHz : IN std_ulogic; clkin_133MHz : IN std_ulogic; reset : IN std_ulogic; - vga_r, vga_g, vga_b : OUT std_ulogic_vector(3 downto 0); + vga_r, vga_g, vga_b : OUT std_logic_vector(3 downto 0); vga_vsync, vga_hsync : OUT std_ulogic; dataflash_mosi, dataflash_sck, dataflash_ss, dataflash_wp, dataflash_rst : OUT std_ulogic; dataflash_miso : IN std_ulogic; @@ -86,7 +86,7 @@ architecture testbench of toplevel_tb is signal clkin_50MHz : std_ulogic := '0'; signal clkin_133MHz : std_ulogic := '0'; signal reset : std_ulogic := '0'; - signal vga_r, vga_g, vga_b : std_ulogic_vector(3 downto 0); + signal vga_r, vga_g, vga_b : std_logic_vector(3 downto 0); signal vga_vsync, vga_hsync : std_ulogic; signal dataflash_mosi, dataflash_sck, dataflash_ss, dataflash_wp, dataflash_rst : std_ulogic; signal dataflash_miso : std_ulogic; @@ -108,6 +108,8 @@ architecture testbench of toplevel_tb is signal ddr2_ck : std_logic_vector(0 downto 0); signal ddr2_ck_n : std_logic_vector(0 downto 0); + signal sim_done : boolean := false; + begin -- testbench -- component instantiation @@ -166,8 +168,10 @@ begin -- testbench -- clock generation - clkin_133MHz <= not clkin_133MHz after 3.7594 ns; - clkin_50MHz <= not clkin_50MHz after 10 ns; + clkin_133MHz <= not clkin_133MHz after 3.7594 ns when sim_done = false else + '0'; + clkin_50MHz <= not clkin_50MHz after 10 ns when sim_done = false else + '0'; -- waveform generation WaveGen_Proc: process @@ -186,6 +190,8 @@ begin -- testbench wait for 100 ns; -- wait for uut to stat wait until rising_edge(vga_vsync); -- wait for vga frame to start (depends -- on latency of UUT) + wait for 1061.76 us; + while true loop for y in 479 downto 0 loop for x in 0 to 639 loop @@ -198,10 +204,13 @@ begin -- testbench wait for 1440 us; WriteFile("vga" & integer'image(i) & ".bmp"); i := i + 1; + if i = 2 then + sim_done <= true; + wait; + end if; end loop; end process; - end testbench; ------------------------------------------------------------------------------- diff --git a/tb/vga_tb.vhd b/tb/vga_tb.vhd index 56368dc..04e4e0b 100644 --- a/tb/vga_tb.vhd +++ b/tb/vga_tb.vhd @@ -6,7 +6,7 @@ -- Author : -- Company : -- Created : 2013-03-07 --- Last update: 2013-03-07 +-- Last update: 2013-03-08 -- Platform : -- Standard : VHDL'87 ------------------------------------------------------------------------------- @@ -42,7 +42,7 @@ architecture testbench of vga_tb is mem_rdrq : out std_logic; mem_adr : out std_logic_vector(19 downto 0); mem_ack : in std_logic; - mem_dat_i : in std_logic_vector(31 downto 0); + mem_dat_i : in std_logic_vector(63 downto 0); red : out std_logic_vector(3 downto 0); green : out std_logic_vector(3 downto 0); blue : out std_logic_vector(3 downto 0); @@ -56,7 +56,7 @@ architecture testbench of vga_tb is signal mem_rdrq : std_logic; signal mem_adr : std_logic_vector(19 downto 0); signal mem_ack : std_logic; - signal mem_dat_i : std_logic_vector(31 downto 0); + signal mem_dat_i : std_logic_vector(63 downto 0); signal red : std_logic_vector(3 downto 0); signal green : std_logic_vector(3 downto 0); signal blue : std_logic_vector(3 downto 0); @@ -113,25 +113,25 @@ begin -- testbench row := to_integer(unsigned(mem_adr))/20; column := to_integer(unsigned(mem_adr)) mod 20; wait until rising_edge(clk_in); - for i in 0 to 15 loop + for i in 0 to 7 loop -- draw colour bars if column < 7 then - mem_dat_i <= x"0f000f00"; + mem_dat_i <= x"0f000f000f000f00"; elsif column < 13 then - mem_dat_i <= x"00f000f0"; + mem_dat_i <= x"00f000f000f000f0"; else - mem_dat_i <= x"000f000f"; + mem_dat_i <= x"000f000f000f000f"; end if; -- draw 1px white border if row = 0 or row = 479 then - mem_dat_i <= x"0fff0fff"; + mem_dat_i <= x"0fff0fff0fff0fff"; elsif column = 0 and i = 0 then - mem_dat_i(31 downto 16) <= x"0fff"; - elsif column = 19 and i = 15 then mem_dat_i(15 downto 0) <= x"0fff"; + elsif column = 19 and i = 7 then + mem_dat_i(63 downto 48) <= x"0fff"; end if; - mem_dat_i(31 downto 16) <= std_logic_vector(to_unsigned(column*32+i*2, 16)); - mem_dat_i(15 downto 0) <= std_logic_vector(to_unsigned(column*32+i*2+1, 16)); +-- mem_dat_i(31 downto 16) <= std_logic_vector(to_unsigned(column*32+i*2, 16)); +-- mem_dat_i(15 downto 0) <= std_logic_vector(to_unsigned(column*32+i*2+1, 16)); mem_ack <= '1'; wait until rising_edge(clk_in); end loop; @@ -163,6 +163,10 @@ begin -- testbench wait for 1440 us; WriteFile("vga" & integer'image(i) & ".bmp"); i := i + 1; + if i = 4 then + sim_done <= true; + wait; + end if; end loop; end process; diff --git a/tb/wb_ddr_ctrl_wb_sc_fe_tb.vhd b/tb/wb_ddr_ctrl_wb_sc_fe_tb.vhd index cdb63ed..ae16ffe 100644 --- a/tb/wb_ddr_ctrl_wb_sc_fe_tb.vhd +++ b/tb/wb_ddr_ctrl_wb_sc_fe_tb.vhd @@ -6,7 +6,7 @@ -- Author : -- Company : -- Created : 2013-03-03 --- Last update: 2013-03-05 +-- Last update: 2013-03-08 -- Platform : -- Standard : VHDL'87 ------------------------------------------------------------------------------- @@ -56,19 +56,19 @@ architecture testbench of wb_ddr_ctrl_wb_sc_fe_tb is mem_adr : out std_logic_vector(addr_width-line_size_ln2-1 downto 0); mem_rdrq : out std_logic; mem_wrrq : out std_logic; - mem_dat_o : out std_logic_vector(31 downto 0); + mem_dat_o : out std_logic_vector(63 downto 0); mem_ack : in std_logic; - mem_dat_i : in std_logic_vector(31 downto 0)); + mem_dat_i : in std_logic_vector(63 downto 0)); end component; -- component generics - constant line_size : integer := 16; + constant line_size : integer := 8; constant lines : integer := 64; constant assoc : integer := 2; - constant line_size_ln2 : integer := 4; + constant line_size_ln2 : integer := 3; constant lines_ln2 : integer := 6; constant assoc_ln2 : integer := 1; - constant addr_width : integer := 24; + constant addr_width : integer := 23; -- component ports signal clk_i : std_logic := '0'; @@ -80,9 +80,9 @@ architecture testbench of wb_ddr_ctrl_wb_sc_fe_tb is signal mem_adr : std_logic_vector(addr_width-line_size_ln2-1 downto 0); signal mem_rdrq : std_logic; signal mem_wrrq : std_logic; - signal mem_dat_o : std_logic_vector(31 downto 0); + signal mem_dat_o : std_logic_vector(63 downto 0); signal mem_ack : std_logic := '0'; - signal mem_dat_i : std_logic_vector(31 downto 0) := (others => '-'); + signal mem_dat_i : std_logic_vector(63 downto 0) := (others => '-'); signal endsim : boolean := false; @@ -145,7 +145,7 @@ begin -- testbench while wbs_o.ack_o = '0' loop wait until rising_edge(clk_i); end loop; - assert wbs_o.dat_o = x"ffff000f" report "Read fail: expected 0xffff000f, got " & to_hstring(wbs_o.dat_o) severity error; + assert wbs_o.dat_o = x"ffff000f" report "Read fail: expected 0xffff000f, got " & to_hstring(wbs_o.dat_o) severity failure; wbs_i.cyc_i <= '0'; wbs_i.stb_i <= '0'; wait until rising_edge(clk_i); @@ -159,7 +159,7 @@ begin -- testbench while wbs_o.ack_o = '0' loop wait until rising_edge(clk_i); end loop; - assert wbs_o.dat_o = x"ffff200f" report "Read fail: expected 0xffff200f, got " & to_hstring(wbs_o.dat_o) severity error; + assert wbs_o.dat_o = x"ffff200f" report "Read fail: expected 0xffff200f, got " & to_hstring(wbs_o.dat_o) severity failure; wbs_i.cyc_i <= '0'; wbs_i.stb_i <= '0'; wait until rising_edge(clk_i); @@ -173,7 +173,7 @@ begin -- testbench while wbs_o.ack_o = '0' loop wait until rising_edge(clk_i); end loop; - assert wbs_o.dat_o = x"ffff005f" report "Read fail: expected 0xffff005f, got " & to_hstring(wbs_o.dat_o) severity error; + assert wbs_o.dat_o = x"ffff005f" report "Read fail: expected 0xffff005f, got " & to_hstring(wbs_o.dat_o) severity failure; wbs_i.cyc_i <= '0'; wbs_i.stb_i <= '0'; wait until rising_edge(clk_i); @@ -187,7 +187,7 @@ begin -- testbench while wbs_o.ack_o = '0' loop wait until rising_edge(clk_i); end loop; - assert wbs_o.dat_o = x"00000000" report "Read fail: expected 0x00000000, got "& to_hstring(wbs_o.dat_o) severity error; + assert wbs_o.dat_o = x"00000000" report "Read fail: expected 0x00000000, got "& to_hstring(wbs_o.dat_o) severity failure; wbs_i.cyc_i <= '0'; wbs_i.stb_i <= '0'; wait until rising_edge(clk_i); @@ -216,7 +216,7 @@ begin -- testbench while wbs_o.ack_o = '0' loop wait until rising_edge(clk_i); end loop; - assert wbs_o.dat_o = x"ffff005f" report "Read fail: expected 0xffff005f, got " & to_hstring(wbs_o.dat_o) severity error; + assert wbs_o.dat_o = x"ffff005f" report "Read fail: expected 0xffff005f, got " & to_hstring(wbs_o.dat_o) severity failure; wbs_i.cyc_i <= '0'; wbs_i.stb_i <= '0'; wait until rising_edge(clk_i); @@ -230,7 +230,7 @@ begin -- testbench while wbs_o.ack_o = '0' loop wait until rising_edge(clk_i); end loop; - assert wbs_o.dat_o = x"ffff202f" report "Read fail: expected 0xffff202f, got " & to_hstring(wbs_o.dat_o) severity error; + assert wbs_o.dat_o = x"ffff202f" report "Read fail: expected 0xffff202f, got " & to_hstring(wbs_o.dat_o) severity failure; wbs_i.cyc_i <= '0'; wbs_i.stb_i <= '0'; wait until rising_edge(clk_i); @@ -244,7 +244,7 @@ begin -- testbench while wbs_o.ack_o = '0' loop wait until rising_edge(clk_i); end loop; - assert wbs_o.dat_o = x"deadbeef" report "Read fail: expected 0xdeadbeef, got " & to_hstring(wbs_o.dat_o) severity error; + assert wbs_o.dat_o = x"deadbeef" report "Read fail: expected 0xdeadbeef, got " & to_hstring(wbs_o.dat_o) severity failure; wbs_i.cyc_i <= '0'; wbs_i.stb_i <= '0'; wait until rising_edge(clk_i); @@ -258,7 +258,7 @@ begin -- testbench while wbs_o.ack_o = '0' loop wait until rising_edge(clk_i); end loop; - assert wbs_o.dat_o = x"ffff01ff" report "Read fail: expected 0xffff01ff, got " & to_hstring(wbs_o.dat_o) severity error; + assert wbs_o.dat_o = x"ffff01ff" report "Read fail: expected 0xffff01ff, got " & to_hstring(wbs_o.dat_o) severity failure; wbs_i.cyc_i <= '0'; wbs_i.stb_i <= '0'; wait until rising_edge(clk_i); @@ -272,7 +272,7 @@ begin -- testbench while wbs_o.ack_o = '0' loop wait until rising_edge(clk_i); end loop; - assert wbs_o.dat_o = x"ffff21ff" report "Read fail: expected 0xffff21ff, got " & to_hstring(wbs_o.dat_o) severity error; + assert wbs_o.dat_o = x"ffff21ff" report "Read fail: expected 0xffff21ff, got " & to_hstring(wbs_o.dat_o) severity failure; wbs_i.cyc_i <= '0'; wbs_i.stb_i <= '0'; wbs_i.adr_i <= (others => '-'); @@ -333,7 +333,7 @@ begin -- testbench while wbs_o.ack_o = '0' loop wait until rising_edge(clk_i); end loop; - assert wbs_o.dat_o = x"deadbeef" report "Read fail: expected 0xdeadbeef, got " & to_hstring(wbs_o.dat_o) severity error; + assert wbs_o.dat_o = x"deadbeef" report "Read fail: expected 0xdeadbeef, got " & to_hstring(wbs_o.dat_o) severity failure; wbs_i.cyc_i <= '0'; wbs_i.stb_i <= '0'; wait until rising_edge(clk_i); @@ -361,7 +361,7 @@ begin -- testbench for i in 0 to line_size-1 loop wait until rising_edge(clk_i); mem_ack <= '1'; - mem_dat_i <= mem(base_adr*line_size+i); + mem_dat_i <= mem(base_adr*line_size*2+i*2+1) & mem(base_adr*line_size*2+i*2); end loop; wait until rising_edge(clk_i); mem_ack <= '0'; @@ -371,7 +371,8 @@ begin -- testbench wait until rising_edge(clk_i); for i in 0 to line_size-1 loop wait until rising_edge(clk_i); - mem(base_adr*line_size+i) := mem_dat_o; + mem(base_adr*line_size*2+i*2) := mem_dat_o(31 downto 0); + mem(base_adr*line_size*2+i*2+1) := mem_dat_o(63 downto 32); end loop; mem_ack <= '0'; end if; diff --git a/tb/wb_ddr_ctrl_wb_sc_tb.vhd b/tb/wb_ddr_ctrl_wb_sc_tb.vhd new file mode 100644 index 0000000..8d82532 --- /dev/null +++ b/tb/wb_ddr_ctrl_wb_sc_tb.vhd @@ -0,0 +1,316 @@ +------------------------------------------------------------------------------- +-- Title : Testbench for design "wb_ddr_ctrl_wb_sc" +-- Project : +------------------------------------------------------------------------------- +-- File : wb_ddr_ctrl_wb_sc_tb.vhd +-- Author : +-- Company : +-- Created : 2013-03-08 +-- Last update: 2013-03-08 +-- Platform : +-- Standard : VHDL'87 +------------------------------------------------------------------------------- +-- Description: +------------------------------------------------------------------------------- +-- Copyright (c) 2013 +------------------------------------------------------------------------------- +-- Revisions : +-- Date Version Author Description +-- 2013-03-08 1.0 Matthias Created +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library ieee_proposed; +use ieee_proposed.std_logic_1164_additions.all; + +use work.intercon_package.all; +------------------------------------------------------------------------------- + +entity wb_ddr_ctrl_wb_sc_tb is + +end wb_ddr_ctrl_wb_sc_tb; + +------------------------------------------------------------------------------- + +architecture testbench of wb_ddr_ctrl_wb_sc_tb is + + component wb_ddr_ctrl_wb_sc + generic ( + burst_length : integer; + burst_length_ln2 : integer; + dontcare : std_logic); + port ( + clk_i : in std_ulogic; + rst_i : in std_ulogic; + wbs_i : in sdram_ctrl_wbs_i_type; + wbs_o : out sdram_ctrl_wbs_o_type; + wbs_cc_i : in sdram_ctrl_cc_wbs_i_type; + wbs_cc_o : out sdram_ctrl_cc_wbs_o_type; + vga_mem_rdrq : in std_logic; + vga_mem_adr : in std_logic_vector(19 downto 0); + vga_mem_ack : out std_logic; + vga_mem_dat_i : out std_logic_vector(63 downto 0); + ddr_din : out std_logic_vector(63 downto 0); + ddr_dout : in std_logic_vector(63 downto 0); + ddr_adr : out std_logic_vector(22 downto 0); + ddr_we : out std_ulogic; + ddr_be : out std_logic_vector(7 downto 0); + fifo_to_ddr_write : out std_ulogic; + fifo_from_ddr_read : out std_ulogic; + fifo_to_ddr_full : in std_ulogic; + fifo_from_ddr_empty : in std_ulogic); + end component; + + -- component generics + constant burst_length : integer := 8; + constant burst_length_ln2 : integer := 3; + constant dontcare : std_logic := '0'; + + -- component ports + signal clk_i : std_ulogic := '0'; + signal rst_i : std_ulogic := '1'; + signal wbs_i : sdram_ctrl_wbs_i_type; + signal wbs_o : sdram_ctrl_wbs_o_type; + signal wbs_cc_i : sdram_ctrl_cc_wbs_i_type; + signal wbs_cc_o : sdram_ctrl_cc_wbs_o_type; + signal vga_mem_rdrq : std_logic := '0'; + signal vga_mem_adr : std_logic_vector(19 downto 0); + signal vga_mem_ack : std_logic; + signal vga_mem_dat_i : std_logic_vector(63 downto 0); + signal ddr_din : std_logic_vector(63 downto 0); + signal ddr_dout : std_logic_vector(63 downto 0); + signal ddr_adr : std_logic_vector(22 downto 0); + signal ddr_we : std_ulogic; + signal ddr_be : std_logic_vector(7 downto 0); + signal fifo_to_ddr_write : std_ulogic; + signal fifo_from_ddr_read : std_ulogic; + signal fifo_to_ddr_full : std_ulogic := '0'; + signal fifo_from_ddr_empty : std_ulogic := '1'; + + signal sim_done : boolean := false; + constant maxdelay : integer := 8; + signal delay : integer range 0 to maxdelay := 2; + signal readrate : integer := 0; + + type fifo_a is array(0 to 127) of std_logic_vector(22 downto 0); + signal fifo : fifo_a := (others => (others => '0')); + signal fifo_rdptr, fifo_wrptr : integer range 0 to 127; + + type wrptr_dly_a is array(maxdelay downto 0) of integer range 0 to 127; + signal wrptr_dly : wrptr_dly_a := (others => 0); + +begin -- testbench + + -- component instantiation + DUT: wb_ddr_ctrl_wb_sc + generic map ( + burst_length => burst_length, + burst_length_ln2 => burst_length_ln2, + dontcare => dontcare) + port map ( + clk_i => clk_i, + rst_i => rst_i, + wbs_i => wbs_i, + wbs_o => wbs_o, + wbs_cc_i => wbs_cc_i, + wbs_cc_o => wbs_cc_o, + vga_mem_rdrq => vga_mem_rdrq, + vga_mem_adr => vga_mem_adr, + vga_mem_ack => vga_mem_ack, + vga_mem_dat_i => vga_mem_dat_i, + ddr_din => ddr_din, + ddr_dout => ddr_dout, + ddr_adr => ddr_adr, + ddr_we => ddr_we, + ddr_be => ddr_be, + fifo_to_ddr_write => fifo_to_ddr_write, + fifo_from_ddr_read => fifo_from_ddr_read, + fifo_to_ddr_full => fifo_to_ddr_full, + fifo_from_ddr_empty => fifo_from_ddr_empty); + + -- clock generation + clk_i <= not clk_i after 10 ns when not sim_done else + '0'; + + -- waveform generation + WaveGen_Proc: process + variable ctr : integer; + variable expected_data : std_logic_vector(63 downto 0); + begin + -- insert signal assignments here + rst_i <= '1'; + + wait for 50 ns; + wait until rising_edge(clk_i); + + rst_i <= '0'; + wait until rising_edge(clk_i); + + vga_mem_rdrq <= '1'; + vga_mem_adr <= x"00010"; + wait until rising_edge(clk_i); + vga_mem_rdrq <= '0'; + + ctr := 0; + while ctr < burst_length loop + if vga_mem_ack = '1' then + expected_data := (others => '0'); + expected_data(22 downto 3) := x"00010"; + expected_data(2 downto 0) := std_logic_vector(to_unsigned(ctr, 3)); + assert vga_mem_dat_i = expected_data report "Incorrect read data (VGA)" severity failure; + ctr := ctr + 1; + end if; + + wait until rising_edge(clk_i); + end loop; + + vga_mem_rdrq <= '1'; + vga_mem_adr <= x"10010"; + wait until rising_edge(clk_i); + vga_mem_rdrq <= '0'; + + ctr := 0; + while ctr < burst_length loop + if vga_mem_ack = '1' then + expected_data := (others => '0'); + expected_data(22 downto 3) := x"10010"; + expected_data(2 downto 0) := std_logic_vector(to_unsigned(ctr, 3)); + assert vga_mem_dat_i = expected_data report "Incorrect read data (VGA)" severity failure; + ctr := ctr + 1; + end if; + + wait until rising_edge(clk_i); + end loop; + + -- read miss w/o replace (tag 1 index 1) + wbs_i.cyc_i <= '1'; + wbs_i.stb_i <= '1'; + wbs_i.we_i <= '0'; + wbs_i.adr_i <= x"000210"; + wait until rising_edge(clk_i); + while wbs_o.ack_o = '0' loop + wait until rising_edge(clk_i); + end loop; + assert wbs_o.dat_o = x"00000108" report "Read fail: expected 0x00000108, got " & to_hstring(wbs_o.dat_o) severity failure; + wbs_i.cyc_i <= '0'; + wbs_i.stb_i <= '0'; + wait until rising_edge(clk_i); + + -- write miss (tag 2 index 0) + wbs_i.cyc_i <= '1'; + wbs_i.stb_i <= '1'; + wbs_i.we_i <= '1'; + wbs_i.adr_i <= x"000404"; + wbs_i.dat_i <= x"deadbeef"; + wbs_i.sel_i <= "1111"; + wait until rising_edge(clk_i); + while wbs_o.ack_o = '0' loop + wait until rising_edge(clk_i); + end loop; + wbs_i.cyc_i <= '0'; + wbs_i.stb_i <= '0'; + wait until rising_edge(clk_i); + + -- manual flush + wbs_cc_i.cyc_i <= '1'; + wbs_cc_i.stb_i <= '1'; + wbs_cc_i.we_i <= '1'; + wbs_cc_i.adr_i <= "0"; + wbs_cc_i.dat_i <= x"00001010"; + wbs_cc_i.sel_i <= "1111"; + wait until rising_edge(clk_i); + while wbs_cc_o.ack_o = '0' loop + wait until rising_edge(clk_i); + end loop; + wbs_cc_i.cyc_i <= '0'; + wbs_cc_i.stb_i <= '0'; + wait until rising_edge(clk_i); + + -- read miss w/o replace (tag 3 index 1) + wbs_i.cyc_i <= '1'; + wbs_i.stb_i <= '1'; + wbs_i.we_i <= '0'; + wbs_i.adr_i <= x"000612"; + wait until rising_edge(clk_i); + while wbs_o.ack_o = '0' loop + wait until rising_edge(clk_i); + end loop; + assert wbs_o.dat_o = x"00000309" report "Read fail: expected 0x00000309, got " & to_hstring(wbs_o.dat_o) severity failure; + wbs_i.cyc_i <= '0'; + wbs_i.stb_i <= '0'; + wait until rising_edge(clk_i); + + wait until rising_edge(clk_i); + wait until rising_edge(clk_i); + sim_done <= true; + wait; + end process WaveGen_Proc; + + emul_fifo_to_ddr : process + constant max_fill : integer := 7; + variable fill : integer := 0; + variable ctr : integer := 0; + begin + wait until rst_i = '0'; + while true loop + wait until rising_edge(clk_i); + if fifo_to_ddr_write = '1' then + assert fill < max_fill report "DUT->DDR FIFO overflow" severity failure; + if ddr_we = '0' then + fifo(fifo_wrptr) <= ddr_adr; + fifo_wrptr <= (fifo_wrptr + 1) mod 128; + end if; + fill := fill + 1; + end if; + if ctr >= readrate then + fill := fill - 1; + ctr := 0; + else + ctr := ctr + 1; + end if; + if fill >= max_fill then + fifo_to_ddr_full <= '1'; + else + fifo_to_ddr_full <= '0'; + end if; + end loop; + end process emul_fifo_to_ddr; + + emul_fifo_from_ddr : process + + variable rdptr_next : integer range 0 to 127; + begin + wait until rst_i = '0'; + while true loop + wait until rising_edge(clk_i); + wrptr_dly <= wrptr_dly(maxdelay-1 downto 0) & fifo_wrptr; + + rdptr_next := fifo_rdptr; + if fifo_from_ddr_read = '1' then + assert wrptr_dly(delay) /= fifo_rdptr report "DDR->DUT FIFO underflow" severity failure; + ddr_dout(63 downto 23) <= (others => '0'); + ddr_dout(22 downto 0) <= fifo(fifo_rdptr); + rdptr_next := (fifo_rdptr + 1) mod 128; + end if; + if wrptr_dly(delay) = rdptr_next then + fifo_from_ddr_empty <= '1'; + else + fifo_from_ddr_empty <= '0'; + end if; + fifo_rdptr <= rdptr_next; + end loop; + end process emul_fifo_from_ddr; + +end testbench; + +------------------------------------------------------------------------------- + +configuration wb_ddr_ctrl_wb_sc_tb_testbench_cfg of wb_ddr_ctrl_wb_sc_tb is + for testbench + end for; +end wb_ddr_ctrl_wb_sc_tb_testbench_cfg; + +------------------------------------------------------------------------------- diff --git a/wb_ddr_ctrl_wb_sc_tb.wcfg b/wb_ddr_ctrl_wb_sc_tb.wcfg new file mode 100644 index 0000000..8c8352f --- /dev/null +++ b/wb_ddr_ctrl_wb_sc_tb.wcfg @@ -0,0 +1,611 @@ + + + + + + + + + + + + + + + + + + + + sim_done + sim_done + + + delay + delay + + + readrate + readrate + + + fifo[0:127] + fifo[0:127] + + + fifo_rdptr + fifo_rdptr + + + fifo_wrptr + fifo_wrptr + + + wrptr_dly[8:0] + wrptr_dly[8:0] + + + clk_i + clk_i + + + rst_i + rst_i + + + wbs_i + wbs_i + + .dat_i + wbs_i.dat_i + HEXRADIX + + + .we_i + wbs_i.we_i + + + .sel_i + wbs_i.sel_i + + + .adr_i + wbs_i.adr_i + HEXRADIX + + + .bte_i + wbs_i.bte_i + + + .cti_i + wbs_i.cti_i + + + .cyc_i + wbs_i.cyc_i + + + .stb_i + wbs_i.stb_i + + + + wbs_o + wbs_o + + .dat_o + wbs_o.dat_o + HEXRADIX + + + .ack_o + wbs_o.ack_o + + + + wbs_cc_i + wbs_cc_i + + .dat_i + wbs_cc_i.dat_i + HEXRADIX + + + .we_i + wbs_cc_i.we_i + + + .sel_i + wbs_cc_i.sel_i + + + .adr_i + wbs_cc_i.adr_i + + + .cyc_i + wbs_cc_i.cyc_i + + + .stb_i + wbs_cc_i.stb_i + + + + wbs_cc_o + wbs_cc_o + + .dat_o + wbs_cc_o.dat_o + HEXRADIX + + + .ack_o + wbs_cc_o.ack_o + + + + vga_mem_rdrq + vga_mem_rdrq + + + vga_mem_adr[19:0] + vga_mem_adr[19:0] + HEXRADIX + + + vga_mem_ack + vga_mem_ack + + + vga_mem_dat_i[63:0] + vga_mem_dat_i[63:0] + HEXRADIX + + + ddr_din[63:0] + ddr_din[63:0] + HEXRADIX + + + ddr_dout[63:0] + ddr_dout[63:0] + HEXRADIX + + + ddr_adr[22:0] + ddr_adr[22:0] + HEXRADIX + + + ddr_we + ddr_we + + + ddr_be[7:0] + ddr_be[7:0] + + + fifo_to_ddr_write + fifo_to_ddr_write + + + fifo_from_ddr_read + fifo_from_ddr_read + + + fifo_to_ddr_full + fifo_to_ddr_full + + + fifo_from_ddr_empty + fifo_from_ddr_empty + + + cfe_mem_adr[19:0] + cfe_mem_adr[19:0] + + + cfe_mem_rdrq + cfe_mem_rdrq + + + cfe_mem_wrrq + cfe_mem_wrrq + + + cfe_mem_dat_o[63:0] + cfe_mem_dat_o[63:0] + HEXRADIX + + + cfe_mem_ack + cfe_mem_ack + + + cfe_mem_dat_i[63:0] + cfe_mem_dat_i[63:0] + HEXRADIX + + + vga_rdrq_reg + vga_rdrq_reg + + + vga_adr_reg[19:0] + vga_adr_reg[19:0] + + + vga_rq_complete + vga_rq_complete + + + cfe_rdrq_reg + cfe_rdrq_reg + + + cfe_wrrq_reg + cfe_wrrq_reg + + + cfe_adr_reg[19:0] + cfe_adr_reg[19:0] + + + cfe_rq_complete + cfe_rq_complete + + + dout_data_valid + dout_data_valid + + + bus_owner + bus_owner + + + bus_owner_reg + bus_owner_reg + + + out_ctr + out_ctr + + + in_ctr + in_ctr + + + out_complete + out_complete + + + in_complete + in_complete + + + in_read + in_read + + + in_write + in_write + + + ddr_adr_int[22:0] + ddr_adr_int[22:0] + + + ddr_adr_dly[1:0] + ddr_adr_dly[1:0] + + + ddr_we_int + ddr_we_int + + + ddr_we_dly[1:0] + ddr_we_dly[1:0] + + + fifo_to_ddr_write_int + fifo_to_ddr_write_int + + + fifo_to_ddr_write_dly[1:0] + fifo_to_ddr_write_dly[1:0] + + + out_complete_dly[1:0] + out_complete_dly[1:0] + + + CFE + label + + wbs_i + wbs_i + + + wbs_o + wbs_o + + .dat_o + wbs_o.dat_o + HEXRADIX + + + .ack_o + wbs_o.ack_o + + + + wbs_cc_i + wbs_cc_i + + + wbs_cc_o + wbs_cc_o + + + mem_adr[19:0] + mem_adr[19:0] + + + mem_rdrq + mem_rdrq + + + mem_wrrq + mem_wrrq + + + mem_dat_o[63:0] + mem_dat_o[63:0] + + + mem_ack + mem_ack + + + mem_dat_i[63:0] + mem_dat_i[63:0] + + + cc_tag[31:0] + cc_tag[31:0] + + + cc_lru[31:0] + cc_lru[31:0] + + + cc_valid[31:0] + cc_valid[31:0] + + + cc_dirty[31:0] + cc_dirty[31:0] + + + cc_we + cc_we + + + cc_wr_addr[4:0] + cc_wr_addr[4:0] + + + cc_rd_addr[4:0] + cc_rd_addr[4:0] + + + cc_tag_wr_data[29:0] + cc_tag_wr_data[29:0] + HEXRADIX + + + cc_tag_rd_data[29:0] + cc_tag_rd_data[29:0] + HEXRADIX + + + cc_lru_wr_data[1:0] + cc_lru_wr_data[1:0] + + + cc_lru_rd_data[1:0] + cc_lru_rd_data[1:0] + + + cc_valid_wr_data[1:0] + cc_valid_wr_data[1:0] + + + cc_valid_rd_data[1:0] + cc_valid_rd_data[1:0] + + + cc_dirty_wr_data[1:0] + cc_dirty_wr_data[1:0] + + + cc_dirty_rd_data[1:0] + cc_dirty_rd_data[1:0] + + + tags[1:0] + tags[1:0] + HEXRADIX + + + cache[511:0] + cache[511:0] + + + cache_wr_addr[8:0] + cache_wr_addr[8:0] + UNSIGNEDDECRADIX + + + cache_rd_addr[8:0] + cache_rd_addr[8:0] + HEXRADIX + + + cache_wr_data[63:0] + cache_wr_data[63:0] + + + cache_rd_data[63:0] + cache_rd_data[63:0] + + + cache_bwe[7:0] + cache_bwe[7:0] + HEXRADIX + + + cache_di7[7:0] + cache_di7[7:0] + HEXRADIX + + + cache_di6[7:0] + cache_di6[7:0] + HEXRADIX + + + cache_di5[7:0] + cache_di5[7:0] + HEXRADIX + + + cache_di4[7:0] + cache_di4[7:0] + HEXRADIX + + + cache_di3[7:0] + cache_di3[7:0] + HEXRADIX + + + cache_di2[7:0] + cache_di2[7:0] + HEXRADIX + + + cache_di1[7:0] + cache_di1[7:0] + HEXRADIX + + + cache_di0[7:0] + cache_di0[7:0] + HEXRADIX + + + adr_index[4:0] + adr_index[4:0] + UNSIGNEDDECRADIX + + + adr_offset[2:0] + adr_offset[2:0] + UNSIGNEDDECRADIX + + + adr_tag[14:0] + adr_tag[14:0] + HEXRADIX + + + adr_tag_eq[1:0] + adr_tag_eq[1:0] + + + lru_eq0[1:0] + lru_eq0[1:0] + + + adr_tag_eq_num[0:0] + adr_tag_eq_num[0:0] + + + eject_num[0:0] + eject_num[0:0] + + + update_lru + update_lru + + + set_dirty + set_dirty + + + set_valid + set_valid + + + cache_write + cache_write + + + cache_from_mem + cache_from_mem + + + eject_dirty + eject_dirty + + + set_invalid + set_invalid + + + cache_to_mem + cache_to_mem + + + user_cc + user_cc + + + adr_tag_eq_num_dirty + adr_tag_eq_num_dirty + + + mem_offset[2:0] + mem_offset[2:0] + UNSIGNEDDECRADIX + + + mem_offset_dly[2:0] + mem_offset_dly[2:0] + UNSIGNEDDECRADIX + + + mem_rdrq_int + mem_rdrq_int + + + mem_wrrq_int + mem_wrrq_int + + + user_cc_req_flush + user_cc_req_flush + + + user_cc_req_inval + user_cc_req_inval + + + user_cc_read + user_cc_read + + +