diff --git a/Makefile b/Makefile index afb8436..2c48886 100755 --- a/Makefile +++ b/Makefile @@ -25,11 +25,10 @@ ddr2_sdram/vhdl_bl4/example_design/rtl/vhdl_bl4_data_path_iobs_0.vhd \ ddr2_sdram/vhdl_bl4/example_design/rtl/vhdl_bl4_s3_dm_iob.vhd \ ddr2_sdram/vhdl_bl4/example_design/rtl/vhdl_bl4_s3_dqs_iob.vhd \ ddr2_sdram/vhdl_bl4/example_design/rtl/vhdl_bl4_s3_dq_iob.vhd \ -src/wb_interconnect.vhd \ +src/wishbone.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_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/bresenham_dp.vhd \ @@ -37,6 +36,7 @@ src/rasterizer_l_fsm.vhd src/rasterizer_l.vhd \ src/mblite_rom_data.vhd src/mblite_rom.vhd src/mblite_wrapper.vhd src/pio.vhd \ src/uart/fifo16x8.vhd src/uart/par2ser.vhd src/uart/pulsegen325.vhd src/uart/readctrl.vhd src/uart/ser2par.vhd \ src/uart/writectrl.vhd src/uart/uart.vhd src/uart/uart_wbc.vhd \ +src/ram_16x64.vhd src/wb_mem_bridge.vhd \ src/toplevel.vhd MBLITE_INFILES=mblite/config_Pkg.vhd mblite/std_Pkg.vhd mblite/core_Pkg.vhd \ mblite/dsram.vhd mblite/gprf.vhd mblite/fetch.vhd mblite/decode.vhd mblite/execute.vhd mblite/mem.vhd \ @@ -45,6 +45,7 @@ SYN_INFILES= PSMFILES= CORES=wb_ddr_ctrl_wb_from_ddr wb_ddr_ctrl_wb_to_ddr vga_pixeldata_fifo BMMFILE=mblite_rom.bmm +BMMFILE_BD=mblite_rom_bd.bmm MEMFILE=test.mem PRJNAME=2d_display_engine NGCFILE=$(PRJNAME).ngc @@ -56,6 +57,7 @@ NGDFILE=$(PRJNAME).ngd NCDFILE=$(PRJNAME).ncd NCDFILE_R=$(PRJNAME)_routed.ncd BITFILE=$(PRJNAME).bit +FWBITFILE=$(PRJNAME)_bd.bit TWRFILE=$(PRJNAME).twr TWXFILE=$(PRJNAME).twx PRJFILE=$(PRJNAME).prj @@ -117,7 +119,7 @@ FWFILE=firmware/fw.elf .SECONDARY: -all: $(BITFILE) #firmware/fw.elf +all: $(FWBITFILE) synth: $(NGCFILE) @@ -128,13 +130,18 @@ timing: $(TWRFILE) firmware/fw.elf: cd firmware && make fw.elf +bit: $(BITFILE) + +impact: $(FWBITFILE) impact.cmd + impact -batch impact.cmd + #%.vhd: %.psm # ../tools/picoasm/picoasm -t ../tools/picoasm/ROM_form.vhd -i $< src/wb_interconnect.vhd: src/wishbone.defines tools/wishbone.pl cd src && dos2unix wishbone.defines && ../tools/wishbone.pl -nogui wishbone.defines -src/mblite_rom_data.vhd: $(BMMFILE) $(FWFILE) +src/mblite_rom_data.vhd: $(BMMFILE) # $(FWFILE) $(DATA2MEM) -bm $(BMMFILE) -bd $(FWFILE) -o h $@ coregen/%.vhd coregen/%.ngc: coregen/%.xco coregen/coregen.cgp @@ -178,9 +185,11 @@ $(PCFFILE) $(NCDFILE) : $(NGDFILE) $(NCDFILE_R): $(PCFFILE) $(NCDFILE) $(PAR) -w $(PAROPTS) $(NCDFILE) $(NCDFILE_R) $(PCFFILE) -$(BITFILE): $(NCDFILE_R) $(PCFFILE) +$(BITFILE) $(BMMFILE_BD): $(NCDFILE_R) $(PCFFILE) $(BITGEN) -w $(BITGENOPTS) $(NCDFILE_R) $(BITFILE) $(PCFFILE) -#-bd $(MEMFILE) + +$(FWBITFILE): $(BITFILE) $(BMMFILE_BD) $(FWFILE) + $(DATA2MEM) -bm $(BMMFILE_BD) -bt $(BITFILE) -bd $(FWFILE) -o b $@ $(TWRFILE) $(TWXFILE): $(NCDFILE_R) $(PCFFILE) $(TRCE) $(TRACEOPTS) -o $(TWRFILE) $(NCDFILE_R) $(PCFFILE) @@ -191,7 +200,7 @@ isim/ieee_proposed/std_logic_1164_additions.vdb: tools/std_logic_1164_additions. isim/mblite/%.vdb: mblite/%.vhd $(VHPCOMP) --work mblite=isim/mblite $< $(VHPCOMPOPTS) -isim/work/intercon_package.vdb isim/work/intercon.vdb: src/wb_interconnect.vhd +isim/work/intercon_package.vdb isim/work/interconnect.vdb: src/wishbone.vhd $(VHPCOMP) $< $(VHPCOMPOPTS) isim/work/vhdl_bl4_dqs_delay.vdb: ddr2_sdram/vhdl_bl4/example_design/rtl/vhdl_bl4_dqs_delay_0.vhd @@ -222,14 +231,18 @@ isim/work/%.vdb: coregen/%.vhd $(FUSE) work.$(@:.exe=) -o $@ $(FUSEOPTS) clean: - rm -f $(NGCFILE) $(PCFFILE) $(NGDFILE) $(NCDFILE) $(NCDFILE_R) $(BITFILE) $(SIMALLFILESXDB) $(CORESVDB) + rm -f $(NGCFILE) $(PCFFILE) $(NGDFILE) $(NCDFILE) $(NCDFILE_R) $(BITFILE) $(SIMALLFILESXDB) $(CORESVDB) xst/ cd firmware && make clean -.PSEUDO=all synth impl timing clean +.PSEUDO=all synth impl timing clean bit impact isim/work/toplevel_tb.vdb: isim/work/sim_bmppack.vdb isim/work/toplevel.vdb -isim/work/toplevel.vdb: isim/work/mblite_wrapper.vdb isim/work/intercon_package.vdb isim/work/intercon.vdb isim/work/clk_reset.vdb isim/work/wb_ddr_ctrl.vdb isim/work/vga.vdb isim/work/wb_ram.vdb isim/work/pio.vdb isim/work/uart_wbc.vdb +isim/work/wb_ddr_ctrl_wb_sc_tb.vdb: isim/work/wb_ddr_ctrl_wb_sc.vdb + +isim/work/wb_mem_bridge_tb.vdb: isim/work/intercon_package.vdb isim/work/wb_ddr_ctrl_wb_sc.vdb isim/work/wb_mem_bridge.vdb + +isim/work/toplevel.vdb: isim/work/mblite_wrapper.vdb isim/work/intercon_package.vdb isim/work/interconnect.vdb isim/work/clk_reset.vdb isim/work/wb_ddr_ctrl.vdb isim/work/vga.vdb isim/work/wb_ram.vdb isim/work/pio.vdb isim/work/uart_wbc.vdb isim/work/wb_mem_bridge.vdb isim/work/mblite_wrapper.vdb: isim/work/intercon_package.vdb isim/work/mblite_rom.vdb isim/mblite/core_wb.vdb @@ -289,11 +302,11 @@ isim/work/vhdl_bl4_data_path_iobs_0.vdb: isim/work/vhdl_bl4_parameters_0.vdb isi isim/work/wb_ddr_ctrl_wb.vdb: isim/work/intercon_package.vdb isim/work/wb_ddr_ctrl_wb_from_ddr.vdb isim/work/wb_ddr_ctrl_wb_to_ddr.vdb isim/work/wb_ddr_ctrl_wb_sc.vdb isim/work/wb_ddr_ctrl_wb_dc.vdb -isim/work/wb_ddr_ctrl_wb_sc.vdb: isim/work/intercon_package.vdb isim/work/wb_ddr_ctrl_wb_sc_fe.vdb +#isim/work/wb_ddr_ctrl_wb_sc.vdb: isim/work/intercon_package.vdb isim/work/wb_ddr_ctrl_wb_sc_fe.vdb -isim/work/wb_ddr_ctrl_wb_sc_fe.vdb: isim/work/intercon_package.vdb isim/work/wb_ddr_ctrl_wb_sc_fe_fsm.vdb isim/work/wb_ddr_ctrl_wb_sc_fe_ram.vdb +#isim/work/wb_ddr_ctrl_wb_sc_fe.vdb: isim/work/intercon_package.vdb isim/work/wb_ddr_ctrl_wb_sc_fe_fsm.vdb isim/work/wb_ddr_ctrl_wb_sc_fe_ram.vdb -isim/work/wb_ddr_ctrl_wb_sc_fe_fsm.vdb: isim/work/intercon_package.vdb +#isim/work/wb_ddr_ctrl_wb_sc_fe_fsm.vdb: isim/work/intercon_package.vdb isim/work/wb_ddr_ctrl_wb_dc.vdb: isim/work/wb_ddr_ctrl_wb_dc_fsm.vdb @@ -308,3 +321,5 @@ isim/work/pio.vdb: isim/work/intercon_package.vdb isim/work/uart_wbc.vdb: isim/work/uart.vdb isim/work/uart.vdb: isim/work/ser2par.vdb isim/work/readctrl.vdb isim/work/fifo16x8.vdb isim/work/pulsegen325.vdb isim/work/par2ser.vdb isim/work/writectrl.vdb + +isim/work/wb_mem_bridge.vdb: isim/work/intercon_package.vdb isim/work/ram_16x64.vdb diff --git a/constr/2d_display_engine.ucf b/constr/2d_display_engine.ucf index bb3dddc..fff5dd8 100755 --- a/constr/2d_display_engine.ucf +++ b/constr/2d_display_engine.ucf @@ -51,3 +51,9 @@ NET "LED<7>" LOC = "W21" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8; # RS232 NET "RS232_RXD" LOC = "E16" | IOSTANDARD = LVCMOS33; NET "RS232_TXD" LOC = "F15" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW; + +# MicroSD PMOD (in J18) +NET "SD_MISO" LOC = "AA21" | IOSTANDARD = LVCMOS33 | DRIVE = 8; +NET "SD_SCK" LOC = "AB21" | IOSTANDARD = LVCMOS33 | DRIVE = 8; +NET "SD_CS" LOC = "AA19" | IOSTANDARD = LVCMOS33 | DRIVE = 8; +NET "SD_MOSI" LOC = "AB19" | IOSTANDARD = LVCMOS33 | DRIVE = 8; diff --git a/firmware/test.s b/firmware/test.s index 48ad0c8..939c4d5 100644 --- a/firmware/test.s +++ b/firmware/test.s @@ -6,16 +6,56 @@ main: addi r19, r0, helloworld main_loop: lbu r5, r19, r0 - beqi r5, done + beqi r5, fill brlid r15, send_byte addi r19, r19, 1 # delay slot bri main_loop + +fill: + # Clear screen + addi r3, r0, 0x8000000 # r3 = address, load with FB base + addi r4, r0, 0 # r4 = y ctr + addi r7, r0, 0x0f000f00 # Upper/lower border + addi r8, r0, 0x0000000f # Left border + addi r9, r0, 0x00f00000 # Right border +fill_line: + addi r5, r0, 0 # r5 = x ctr +fill_loop: + beqi r4, border + addi r6, r4, -479 + beqi r6, border + beqi r5, lborder + addi r6, r5, -638 + beqi r6, rborder + brid fill_loop_end + sw r0, r3, r0 +border: + brid fill_loop_end + sw r7, r3, r0 +lborder: + brid fill_loop_end + sw r8, r3, r0 +rborder: + sw r9, r3, r0 +fill_loop_end: + addi r3, r3, 4 + addi r6, r5, -638 + beqi r6, fill_loop_nextline + brid fill_loop + addi r5, r5, 2 +fill_loop_nextline: + addi r6, r4, -479 + beqi r6, done + brid fill_line + addi r4, r4, 1 done: - bri done + swi r0, r0, 0x0BFFFFFF # Force mem_bridge buffer flush +idle: + bri idle send_byte: - lbui r3, r0, 0x4024 + lbui r3, r0, 0x4021 andi r3, r3, 0x2 # writefull bnei r3, send_byte rtsd r15, 8 @@ -25,7 +65,7 @@ send_byte: .rodata helloworld: - .asciz "Hello, World!" + .asciz "Hello, World!(2)" .data testdata: diff --git a/impact.cmd b/impact.cmd new file mode 100644 index 0000000..362053c --- /dev/null +++ b/impact.cmd @@ -0,0 +1,6 @@ +setMode -bs +setCable -port auto +identify +assignFile -p 1 -file "2d_display_engine_bd.bit" +program -p 1 -onlyFpga +exit diff --git a/mblite/dsram.vhd b/mblite/dsram.vhd index 162865a..edacc88 100644 --- a/mblite/dsram.vhd +++ b/mblite/dsram.vhd @@ -38,8 +38,12 @@ port end dsram; architecture arch of dsram is - type ram_type is array(2 ** SIZE - 1 downto 0) of std_logic_vector(WIDTH - 1 downto 0); - signal ram : ram_type; + attribute ram_style : string; + + + type ram_type is array(2 ** SIZE - 1 downto 0) of std_logic_vector(WIDTH - 1 downto 0); + signal ram : ram_type; + attribute ram_style of ram : signal is "distributed"; begin process(clk_i) begin diff --git a/src/ram_16x64.vhd b/src/ram_16x64.vhd new file mode 100644 index 0000000..97cfb22 --- /dev/null +++ b/src/ram_16x64.vhd @@ -0,0 +1,70 @@ +------------------------------------------------------------------------------- +-- Title : 16x64 RAM. built from Xilinx LUTRAM primitives +-- Project : +------------------------------------------------------------------------------- +-- File : ram_16x64.vhd +-- Author : Matthias Blankertz +-- Company : +-- Created : 2013-06-04 +-- Last update: 2013-06-04 +-- Platform : +-- Standard : VHDL'93/02 +------------------------------------------------------------------------------- +-- Description: +------------------------------------------------------------------------------- +-- Copyright (c) 2013 +------------------------------------------------------------------------------- +-- Revisions : +-- Date Version Author Description +-- 2013-06-04 1.0 matthias Created +------------------------------------------------------------------------------- + +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 ram_16x64 is + port ( + clk : in std_logic; + bwe : in std_logic_vector(7 downto 0); + adr : in std_logic_vector(3 downto 0); + din : in std_logic_vector(63 downto 0); + dout : out std_logic_vector(63 downto 0) + ); +end ram_16x64; + +architecture Behavioral of ram_16x64 is + signal lut_dout : std_logic_vector(63 downto 0); +begin + gen1: for b in 0 to 7 generate + gen2: for i in 0 to 7 generate + ram_inst : RAM16X1S + port map ( + O => lut_dout(b*8+i), + A0 => adr(0), + A1 => adr(1), + A2 => adr(2), + A3 => adr(3), + D => din(b*8+i), + WCLK => clk, + WE => bwe(b) + ); + end generate; + end generate; + + -- Output register + oreg : process(clk) + begin + if rising_edge(clk) then + dout <= lut_dout; + end if; + end process oreg; +end Behavioral; diff --git a/src/toplevel.vhd b/src/toplevel.vhd index 81e5a08..503f4f0 100755 --- a/src/toplevel.vhd +++ b/src/toplevel.vhd @@ -87,19 +87,25 @@ architecture Mixed of toplevel is signal ram_wbs_i : ram_wbs_i_type; signal rom_wbs_o : mblite_rom_wbs_o_type; signal rom_wbs_i : mblite_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 pio_led_wbs_i : pio_led_wbs_i_type; signal pio_led_wbs_o : pio_led_wbs_o_type; signal uart_wbs_i : uart_wbs_i_type; signal uart_wbs_o : uart_wbs_o_type; + signal mem_bridge_wbs_o : mem_bridge_wbs_o_type; + signal mem_bridge_wbs_i : mem_bridge_wbs_i_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(63 downto 0); + + signal wb_mem_rdrq : std_logic; + signal wb_mem_wrrq : std_logic; + signal wb_mem_adr : std_logic_vector(19 downto 0); + signal wb_mem_dat_o : std_logic_vector(63 downto 0); + signal wb_mem_sel : std_logic_vector(7 downto 0); + signal wb_mem_ack : std_logic; + signal wb_mem_dat_i : std_logic_vector(63 downto 0); signal reset_int : std_logic; @@ -147,15 +153,19 @@ ddr_ctrl0 : entity work.wb_ddr_ctrl clk_i => sysClk, rst_i => sysRst, - wbs_i => sdram_ctrl_wbs_i, - 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_mem_dat_i => vga_mem_dat_i, + + wb_mem_rdrq => wb_mem_rdrq, + wb_mem_wrrq => wb_mem_wrrq, + wb_mem_adr => wb_mem_adr, + wb_mem_dat_o => wb_mem_dat_o, + wb_mem_sel => wb_mem_sel, + wb_mem_ack => wb_mem_ack, + wb_mem_dat_i => wb_mem_dat_i ); vga_1: entity work.vga @@ -236,6 +246,23 @@ uart_inst: entity work.uart_wbc SERIALOUT => rs232_txd ); +mem_bridge_inst : entity work.wb_mem_bridge + port map ( + clk_i => sysClk, + rst_i => sysRst, + + wbs_i => mem_bridge_wbs_i, + wbs_o => mem_bridge_wbs_o, + + wb_mem_rdrq => wb_mem_rdrq, + wb_mem_wrrq => wb_mem_wrrq, + wb_mem_adr => wb_mem_adr, + wb_mem_dat_o => wb_mem_dat_o, + wb_mem_sel => wb_mem_sel, + wb_mem_ack => wb_mem_ack, + wb_mem_dat_i => wb_mem_dat_i + ); + cpu_inst : entity work.mblite_wrapper port map ( clk_i => sysClk, @@ -250,7 +277,7 @@ cpu_inst : entity work.mblite_wrapper fb_flip <= '0'; -intercon_1: entity work.intercon +intercon_1: entity work.interconnect port map ( cpu_wbm_i => cpu_wbm_i, cpu_wbm_o => cpu_wbm_o, @@ -258,15 +285,12 @@ intercon_1: entity work.intercon mblite_rom_wbs_o => rom_wbs_o, ram_wbs_i => ram_wbs_i, 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, + mem_bridge_wbs_i => mem_bridge_wbs_i, + mem_bridge_wbs_o => mem_bridge_wbs_o, pio_led_wbs_o => pio_led_wbs_o, pio_led_wbs_i => pio_led_wbs_i, uart_wbs_o => uart_wbs_o, uart_wbs_i => uart_wbs_i, - dummy_wbm_o => ("----", (others => '-'), "--", "---", '0', '0'), clk => sysClk, reset => sysRst); diff --git a/src/wb_ddr_ctrl.vhd b/src/wb_ddr_ctrl.vhd index 3d161e6..aabb11c 100755 --- a/src/wb_ddr_ctrl.vhd +++ b/src/wb_ddr_ctrl.vhd @@ -61,122 +61,42 @@ entity wb_ddr_ctrl is 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); - - -- Wishbone slave + 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; - - -- Direct memctrl access for VGA + + -- Memory ports + -- Port 0: RO, Prio 0 - VGA controller 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) + vga_mem_dat_i : out std_logic_vector(63 downto 0); + + -- Port 1: RW, Prio 1 - WB bridge + wb_mem_rdrq : in std_logic; + wb_mem_wrrq : in std_logic; + wb_mem_adr : in std_logic_vector(19 downto 0); + wb_mem_dat_o : in std_logic_vector(63 downto 0); + wb_mem_sel : in std_logic_vector(7 downto 0); + wb_mem_ack : out std_logic; + wb_mem_dat_i : out std_logic_vector(63 downto 0) ); end wb_ddr_ctrl; architecture Behavioral of wb_ddr_ctrl is -component wb_ddr_ctrl_ddrwrap is - Port ( - -- DDR2 control - ddr2_clock_in : in std_ulogic; - ddr2_reset : in std_ulogic; - - -- DDR2 ctrl to system - ctrl_input_data : in std_logic_vector(31 downto 0); - ctrl_data_mask : in std_logic_vector(3 downto 0); - ctrl_output_data : out std_logic_vector(31 downto 0) := (others => 'Z'); - ctrl_data_valid : out std_logic; - ctrl_input_address : in std_logic_vector(((13 + 10 + 2)-1) downto 0); - ctrl_command_register : in std_logic_vector(2 downto 0); - ctrl_burst_done : in std_logic; - ctrl_auto_ref_req : out std_logic; - ctrl_cmd_ack : out std_logic; - ctrl_init_done : out std_logic; - ctrl_ar_done : out std_logic; - - -- 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); - - -- Clock out - ddr2_clk0 : out std_ulogic; - ddr2_clk90 : out std_ulogic; - ddr2_clk180 : out std_logic; - ddr2_rst0 : out std_ulogic - ); -end component; - -component wb_ddr_ctrl_wb is - generic ( - dontcare : std_logic := '-' - ); - Port ( - -- Control signals - ddr2_clk0 : in std_ulogic; - ddr2_clk90 : in std_ulogic; - ddr2_clk180 : in std_logic; - ddr2_reset : in std_ulogic; - - -- to DDR2 controller - ctrl_input_data : out std_logic_vector(31 downto 0); - ctrl_data_mask : out std_logic_vector(3 downto 0); - ctrl_output_data : in std_logic_vector(31 downto 0) := (others => 'Z'); - ctrl_data_valid : in std_logic; - ctrl_input_address : out std_logic_vector(((13 + 10 + 2)-1) downto 0); - ctrl_command_register : out std_logic_vector(2 downto 0); - ctrl_burst_done : out std_logic; - ctrl_auto_ref_req : in std_logic; - ctrl_cmd_ack : in std_logic; - ctrl_init_done : in std_logic; - ctrl_ar_done : in std_logic; - - -- Wishbone slave - 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; - - -- 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; - -signal ddr2_clk0, ddr2_clk90, ddr2_clk180 : std_ulogic; -signal ddr2_rst0 : std_ulogic; -signal ctrl_input_data : std_logic_vector(31 downto 0); -signal ctrl_data_mask : std_logic_vector(3 downto 0); -signal ctrl_output_data : std_logic_vector(31 downto 0) := (others => 'Z'); -signal ctrl_data_valid : std_logic; -signal ctrl_input_address : std_logic_vector(((13 + 10 + 2)-1) downto 0); -signal ctrl_command_register : std_logic_vector(2 downto 0); -signal ctrl_burst_done, ctrl_auto_ref_req, ctrl_cmd_ack, ctrl_init_done, ctrl_ar_done : std_logic; + signal ddr2_clk0, ddr2_clk90, ddr2_clk180 : std_ulogic; + signal ddr2_rst0 : std_ulogic; + signal ctrl_input_data : std_logic_vector(31 downto 0); + signal ctrl_data_mask : std_logic_vector(3 downto 0); + signal ctrl_output_data : std_logic_vector(31 downto 0) := (others => 'Z'); + signal ctrl_data_valid : std_logic; + signal ctrl_input_address : std_logic_vector(((13 + 10 + 2)-1) downto 0); + signal ctrl_command_register : std_logic_vector(2 downto 0); + signal ctrl_burst_done, ctrl_auto_ref_req, ctrl_cmd_ack, ctrl_init_done, ctrl_ar_done : std_logic; begin -ddr_0 : wb_ddr_ctrl_ddrwrap +ddr_0 : entity work.wb_ddr_ctrl_ddrwrap port map ( ddr2_clock_in => ddr2_clock, ddr2_reset => ddr2_reset, @@ -217,40 +137,43 @@ ddr_0 : wb_ddr_ctrl_ddrwrap ctrl_ar_done => ctrl_ar_done ); -wb_0 : wb_ddr_ctrl_wb +wb_0 : entity work.wb_ddr_ctrl_wb generic map ( dontcare => dontcare ) - port map ( - clk_i => clk_i, - rst_i => rst_i, - - ddr2_clk0 => ddr2_clk0, - ddr2_clk90 => ddr2_clk90, - ddr2_clk180 => ddr2_clk180, - ddr2_reset => ddr2_rst0, - - ctrl_input_data => ctrl_input_data, - ctrl_data_mask => ctrl_data_mask, - ctrl_output_data => ctrl_output_data, - ctrl_data_valid => ctrl_data_valid, - ctrl_input_address => ctrl_input_address, - ctrl_command_register => ctrl_command_register, - ctrl_burst_done => ctrl_burst_done, - ctrl_auto_ref_req => ctrl_auto_ref_req, - ctrl_cmd_ack => ctrl_cmd_ack, - ctrl_init_done => ctrl_init_done, - ctrl_ar_done => ctrl_ar_done, - - wbs_i => wbs_i, - wbs_o => wbs_o, - wbs_cc_i => wbs_cc_i, - wbs_cc_o => wbs_cc_o, + port map ( + clk_i => clk_i, + rst_i => rst_i, + + ddr2_clk0 => ddr2_clk0, + ddr2_clk90 => ddr2_clk90, + ddr2_clk180 => ddr2_clk180, + ddr2_reset => ddr2_rst0, + + ctrl_input_data => ctrl_input_data, + ctrl_data_mask => ctrl_data_mask, + ctrl_output_data => ctrl_output_data, + ctrl_data_valid => ctrl_data_valid, + ctrl_input_address => ctrl_input_address, + ctrl_command_register => ctrl_command_register, + ctrl_burst_done => ctrl_burst_done, + ctrl_auto_ref_req => ctrl_auto_ref_req, + ctrl_cmd_ack => ctrl_cmd_ack, + ctrl_init_done => ctrl_init_done, + ctrl_ar_done => ctrl_ar_done, - 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_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, + + wb_mem_rdrq => wb_mem_rdrq, + wb_mem_wrrq => wb_mem_wrrq, + wb_mem_adr => wb_mem_adr, + wb_mem_dat_o => wb_mem_dat_o, + wb_mem_sel => wb_mem_sel, + wb_mem_ack => wb_mem_ack, + wb_mem_dat_i => wb_mem_dat_i + ); end Behavioral; diff --git a/src/wb_ddr_ctrl_wb.vhd b/src/wb_ddr_ctrl_wb.vhd index b495435..c24d74d 100755 --- a/src/wb_ddr_ctrl_wb.vhd +++ b/src/wb_ddr_ctrl_wb.vhd @@ -57,19 +57,24 @@ entity wb_ddr_ctrl_wb is ctrl_init_done : in std_logic; ctrl_ar_done : in std_logic; - -- Wishbone slave 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; - - -- Direct memctrl access for VGA + +-- Memory ports + -- Port 0: RO, Prio 0 - VGA controller 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) + vga_mem_dat_i : out std_logic_vector(63 downto 0); + + -- Port 1: RW, Prio 1 - WB bridge + wb_mem_rdrq : in std_logic; + wb_mem_wrrq : in std_logic; + wb_mem_adr : in std_logic_vector(19 downto 0); + wb_mem_dat_o : in std_logic_vector(63 downto 0); + wb_mem_sel : in std_logic_vector(7 downto 0); + wb_mem_ack : out std_logic; + wb_mem_dat_i : out std_logic_vector(63 downto 0) ); end wb_ddr_ctrl_wb; @@ -101,76 +106,6 @@ component wb_ddr_ctrl_wb_to_ddr IS prog_empty : out std_logic ); END component; -component wb_ddr_ctrl_wb_sc is - generic ( - dontcare : std_logic := '-' - ); - Port ( - -- Wishbone slave - 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; - - -- 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); - - -- To/from ddr clock domain - 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 wb_ddr_ctrl_wb_dc is - generic ( - dontcare : std_logic - ); - Port ( - -- Control signals - ddr2_clk0 : in std_ulogic; - ddr2_clk180 : in std_ulogic; - ddr2_clk90 : in std_ulogic; - ddr2_reset : in std_ulogic; - - -- to DDR2 controller - ctrl_input_data : out std_logic_vector(31 downto 0); - ctrl_data_mask : out std_logic_vector(3 downto 0); - ctrl_output_data : in std_logic_vector(31 downto 0) := (others => 'Z'); - ctrl_data_valid : in std_logic; - ctrl_input_address : out std_logic_vector(((13 + 10 + 2)-1) downto 0); - ctrl_command_register : out std_logic_vector(2 downto 0); - ctrl_burst_done : out std_logic; - ctrl_auto_ref_req : in std_logic; - ctrl_cmd_ack : in std_logic; - ctrl_init_done : in std_logic; - ctrl_ar_done : in std_logic; - - -- To/from system clock domain - din : in std_ulogic_vector(63 downto 0); - dout : out std_ulogic_vector(63 downto 0); - adr : in std_ulogic_vector(22 downto 0); - we : in std_ulogic; - be : in std_ulogic_vector(7 downto 0); - - fifo_to_sys_write : out std_ulogic; - fifo_from_sys_read : out std_ulogic; - fifo_to_sys_full : in std_ulogic; - fifo_from_sys_empty : in std_ulogic; - fifo_from_sys_almost_empty : in std_logic - ); -end component; -- FIFO control signals signal s2d_fifo_rd, s2d_fifo_wr, d2s_fifo_rd, d2s_fifo_wr : std_ulogic; @@ -184,23 +119,27 @@ signal d2s_fifo_dout : std_logic_vector(63 downto 0); begin -system_cd_inst : wb_ddr_ctrl_wb_sc +system_cd_inst : entity work.wb_ddr_ctrl_wb_sc generic map ( dontcare => dontcare ) port map ( - -- Wishbone slave 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, + -- Memory ports 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, + + wb_mem_rdrq => wb_mem_rdrq, + wb_mem_wrrq => wb_mem_wrrq, + wb_mem_adr => wb_mem_adr, + wb_mem_dat_o => wb_mem_dat_o, + wb_mem_sel => wb_mem_sel, + wb_mem_ack => wb_mem_ack, + wb_mem_dat_i => wb_mem_dat_i, -- To/from ddr clock domain ddr_din => s2d_fifo_din(63 downto 0), @@ -246,7 +185,7 @@ d2s_fifo : wb_ddr_ctrl_wb_from_ddr dout => d2s_fifo_dout ); -ddr_cd_inst : wb_ddr_ctrl_wb_dc +ddr_cd_inst : entity work.wb_ddr_ctrl_wb_dc generic map ( dontcare => dontcare ) diff --git a/src/wb_ddr_ctrl_wb_sc.vhd b/src/wb_ddr_ctrl_wb_sc.vhd index e0db735..2559240 100755 --- a/src/wb_ddr_ctrl_wb_sc.vhd +++ b/src/wb_ddr_ctrl_wb_sc.vhd @@ -31,8 +31,6 @@ use IEEE.NUMERIC_STD.ALL; --library UNISIM; --use UNISIM.VComponents.all; -use work.intercon_package.all; - entity wb_ddr_ctrl_wb_sc is generic ( burst_length : integer := 8; @@ -40,20 +38,26 @@ entity wb_ddr_ctrl_wb_sc is dontcare : std_logic := '-' ); port ( - -- Wishbone slave 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; - - -- Direct memctrl access for VGA + + -- Memory ports + -- Port 0: RO, Prio 0 - VGA controller 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); + -- Port 1: RW, Prio 1 - WB bridge + wb_mem_rdrq : in std_logic; + wb_mem_wrrq : in std_logic; + wb_mem_adr : in std_logic_vector(19 downto 0); + wb_mem_dat_o : in std_logic_vector(63 downto 0); + wb_mem_sel : in std_logic_vector(7 downto 0); + wb_mem_ack : out std_logic; + wb_mem_dat_i : out std_logic_vector(63 downto 0); + + -- To/from ddr clock domain ddr_din : out std_logic_vector(63 downto 0); ddr_dout : in std_logic_vector(63 downto 0); @@ -69,205 +73,245 @@ entity wb_ddr_ctrl_wb_sc is end wb_ddr_ctrl_wb_sc; architecture Behavioral of wb_ddr_ctrl_wb_sc is - component wb_ddr_ctrl_wb_sc_fe - generic ( - line_size : integer; - lines : integer; - assoc : integer; - line_size_ln2 : integer; - lines_ln2 : integer; - assoc_ln2 : integer; - addr_width : integer; - dontcare : std_logic); - port ( - clk_i : in std_logic; - rst_i : in std_logic; - 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; - 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(63 downto 0); - mem_ack : in std_logic; - mem_dat_i : in std_logic_vector(63 downto 0)); - end component; + -- Memory access controller configuration + constant num_ports : integer := 2; + type port_mode_enum is (M_RO, M_WO, M_RW); + type port_modes_arr is array(0 to num_ports-1) of port_mode_enum; + constant port_modes : port_modes_arr := (M_RO, M_RW); - 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); + -- Configuration-dependant types + type p_slv8_arr is array(num_ports-1 downto 0) of std_logic_vector(7 downto 0); + type p_slv20_arr is array(num_ports-1 downto 0) of std_logic_vector(19 downto 0); + type p_slv64_arr is array(num_ports-1 downto 0) of std_logic_vector(63 downto 0); - 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'; + -- Configuration-dependant signals : Memory ports + signal p_rdrq, p_wrrq : std_logic_vector(num_ports-1 downto 0); + signal p_ack : std_logic_vector(num_ports-1 downto 0) := (others => '0'); + signal p_adr : p_slv20_arr; + signal p_dat_o, p_dat_i : p_slv64_arr; + signal p_sel : p_slv8_arr; + - 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'; + -- Internal signals + signal rdrq_reg, wrrq_reg : std_logic_vector(num_ports-1 downto 0) := (others => '0'); + signal adr_reg : p_slv20_arr; + signal rq_complete : std_logic_vector(num_ports-1 downto 0) := (others => '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; + + constant BUS_IDLE : integer := num_ports; + signal bus_owner, bus_owner_reg : integer range 0 to num_ports := BUS_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'); + --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'; - - signal wbs_i_dly : sdram_ctrl_wbs_i_type; + 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, - dontcare => dontcare - ) - port map ( - clk_i => clk_i, - rst_i => rst_i, - wbs_i => wbs_i_dly, - wbs_o => wbs_o, - wbs_cc_i => wbs_cc_i, - wbs_cc_o => wbs_cc_o, - mem_adr => cfe_mem_adr, - mem_rdrq => cfe_mem_rdrq, - mem_wrrq => cfe_mem_wrrq, - mem_dat_o => cfe_mem_dat_o, - mem_ack => cfe_mem_ack, - mem_dat_i => cfe_mem_dat_i); + -- Attach named memory port signals to internal signals + -- Port 0: RO, Prio 0 - VGA controller + p_rdrq(0) <= vga_mem_rdrq; + p_wrrq(0) <= '0'; + p_adr(0) <= vga_mem_adr; + p_dat_o(0) <= (others => dontcare); + p_sel(0) <= (others => dontcare); + vga_mem_ack <= p_ack(0); + vga_mem_dat_i <= p_dat_i(0); - dly : process(clk_i) - begin - if rising_edge(clk_i) then - wbs_i_dly <= wbs_i; - end if; - end process dly; - - 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'; + -- Port 1: RW, Prio 1 - WB bridge + p_rdrq(1) <= wb_mem_rdrq; + p_wrrq(1) <= wb_mem_wrrq; + p_adr(1) <= wb_mem_adr; + p_dat_o(1) <= wb_mem_dat_o; + p_sel(1) <= wb_mem_sel; + wb_mem_ack <= p_ack(1); + wb_mem_dat_i <= p_dat_i(1); - fifo_from_ddr_read <= not fifo_from_ddr_empty; - ddr_be <= (others => '0'); - 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'; + -- Everything from here on is configured by the constant parameters. + -- No change should be necessary to add a port + + -- Acknowledge signals + p_ack_gen : for i in 0 to num_ports-1 generate + ro_gen : if port_modes(i) = M_RO generate + p_ack(i) <= dout_data_valid when bus_owner_reg = i else + '0'; + end generate; + wo_gen : if port_modes(i) = M_WO generate + p_ack(i) <= not fifo_to_ddr_full when bus_owner = i else + '0'; + end generate; + rw_gen : if port_modes(i) = M_RW generate + p_ack(i) <= dout_data_valid when bus_owner_reg = i and rdrq_reg(i) = '1' else + not fifo_to_ddr_full when bus_owner = i and wrrq_reg(i) = '1' else + '0'; + end generate; + end generate; - 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'); - out_complete_dly <= (others => '0'); - end if; - end if; - end process write_dly; - + -- DDR -> Port data out + p_dat_i_gen : for i in 0 to num_ports-1 generate + ro_rw_gen : if port_modes(i) /= M_WO generate + p_dat_i(i) <= ddr_dout; + end generate; + wo_gen : if port_modes(i) = M_WO generate + p_dat_i(i) <= (others => dontcare); + end generate; + end generate; + + -- Data from DDR via FIFO control 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; + fifo_from_ddr_read <= not fifo_from_ddr_empty; -- Read whenever data is available - 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; + -- Data to DDR via FIFO control + -- Signals from active memory port to DDR + ddr_din_gen : process(p_dat_o, p_sel, bus_owner, fifo_to_ddr_full, out_complete, adr_reg, wrrq_reg) + begin + ddr_din <= (others => dontcare); + ddr_be <= (others => '1'); -- ddr_be is low-active + ddr_adr(22 downto 3) <= (others => dontcare); + ddr_we <= dontcare; + fifo_to_ddr_write <= '0'; + for i in 0 to num_ports-1 loop + if port_modes(i) /= M_RO and bus_owner = i then -- Signals only relevant + -- when writing + ddr_din <= p_dat_o(i); + ddr_be <= not p_sel(i); + end if; + + if port_modes(i) = M_WO and bus_owner = i then -- Write-only ports + fifo_to_ddr_write <= not fifo_to_ddr_full; + elsif port_modes(i) = M_RW and bus_owner = i then -- Read/Write ports + if wrrq_reg(i) = '1' then -- Currently writing + fifo_to_ddr_write <= not fifo_to_ddr_full; + else + fifo_to_ddr_write <= not fifo_to_ddr_full and not out_complete; + end if; + elsif port_modes(i) = M_RO and bus_owner = i then -- Read-only ports + fifo_to_ddr_write <= not fifo_to_ddr_full and not out_complete; + end if; + + if bus_owner = i then -- Signal always relevant + ddr_adr(22 downto 3) <= adr_reg(i); + ddr_we <= wrrq_reg(i); + end if; + end loop; + end process ddr_din_gen; + ddr_adr(2 downto 0) <= std_logic_vector(to_unsigned(out_ctr, 3)); + + + --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'); + -- out_complete_dly <= (others => '0'); + -- end if; + -- end if; + --end process write_dly; + + -- Request registers + rq_regs_gen : for i in 0 to num_ports-1 generate + ro_gen : if port_modes(i) = M_RO generate + rq_regs : process(clk_i) + begin + if rising_edge(clk_i) then + if p_rdrq(i) = '1' then + rdrq_reg(i) <= '1'; + adr_reg(i) <= p_adr(i); + elsif rq_complete(i) = '1' then + rdrq_reg(i) <= '0'; + end if; + end if; + end process rq_regs; + wrrq_reg(i) <= '0'; + end generate; + wo_gen : if port_modes(i) = M_WO generate + rq_regs : process(clk_i) + begin + if rising_edge(clk_i) then + if p_wrrq(i) = '1' then + wrrq_reg(i) <= '1'; + adr_reg(i) <= p_adr(i); + elsif rq_complete(i) = '1' then + wrrq_reg(i) <= '0'; + end if; + end if; + end process rq_regs; + rdrq_reg(i) <= '0'; + end generate; + rw_gen : if port_modes(i) = M_RW generate + rq_regs : process(clk_i) + begin + if rising_edge(clk_i) then + if p_rdrq(i) = '1' then + rdrq_reg(i) <= '1'; + adr_reg(i) <= p_adr(i); + elsif p_wrrq(i) = '1' then + wrrq_reg(i) <= '1'; + adr_reg(i) <= p_adr(i); + elsif rq_complete(i) = '1' then + rdrq_reg(i) <= '0'; + wrrq_reg(i) <= '0'; + end if; + end if; + end process rq_regs; + end generate; + end generate; + + -- Track owner of memory access rights + bus_owner_gen : process(bus_owner_reg, rdrq_reg, wrrq_reg, rq_complete) + begin + bus_owner <= bus_owner_reg; + for i in 0 to num_ports-1 loop + if bus_owner_reg = BUS_IDLE and (rdrq_reg(i) = '1' or wrrq_reg(i) = '1') then + bus_owner <= i; + elsif bus_owner_reg = i and rq_complete(i) = '1' then + bus_owner <= BUS_IDLE; + end if; + end loop; + end process bus_owner_gen; + bus_owner_p : process(clk_i) begin if rising_edge(clk_i) then @@ -281,31 +325,54 @@ begin fifo_to_ddr_full_last <= fifo_to_ddr_full; end if; end process fifo_to_ddr_full_ff; + + -- Track if we are in a read or write state currently + in_stat_gen : process(bus_owner, rdrq_reg, wrrq_reg) + begin + in_read <= '0'; + in_write <= '0'; + for i in 0 to num_ports-1 loop + if bus_owner = i then + if port_modes(i) = M_RO then + in_read <= '1'; + elsif port_modes(i) = M_WO then + in_write <= '1'; + else -- if port_modes(i) = M_RW + in_read <= rdrq_reg(i); + in_write <= wrrq_reg(i); + end if; + end if; + end loop; + end process in_stat_gen; - 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'; - + -- Track request termination + complete_gen : for i in 0 to num_ports-1 generate + ro_gen : if port_modes(i) = M_RO generate + rq_complete(i) <= in_complete and out_complete when bus_owner_reg = i else + '0'; + end generate; + wo_gen : if port_modes(i) = M_WO generate + rq_complete(i) <= out_complete and not fifo_to_ddr_full_last when bus_owner_reg = i else + '0'; + end generate; + rw_gen : if port_modes(i) = M_RW generate + rq_complete(i) <= in_complete and out_complete when bus_owner_reg = i and rdrq_reg(i) = '1' else + out_complete and not fifo_to_ddr_full_last when bus_owner_reg = i and wrrq_reg(i) = '1' else + '0'; + end generate; + end generate; + + -- Count completed cycles of transfer out_ctr_p : process(clk_i) begin if rising_edge(clk_i) then - if (bus_owner /= B_IDLE and out_complete = '0' and fifo_to_ddr_full = '0') then + if (bus_owner /= BUS_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 + elsif unsigned(rq_complete) /= 0 then out_ctr <= 0; out_complete <= '0'; end if; @@ -315,17 +382,28 @@ begin in_ctr_p : process(clk_i) begin if rising_edge(clk_i) then - if bus_owner /= B_IDLE and in_complete = '0' and fifo_from_ddr_empty = '0' then + if bus_owner /= BUS_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 + elsif unsigned(rq_complete) /= 0 then in_ctr <= 0; in_complete <= '0'; end if; end if; end process in_ctr_p; + + + --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'; + + end Behavioral; diff --git a/src/wb_ddr_ctrl_wb_sc_fe.vhd b/src/wb_ddr_ctrl_wb_sc_fe.vhd deleted file mode 100644 index 6780b4c..0000000 --- a/src/wb_ddr_ctrl_wb_sc_fe.vhd +++ /dev/null @@ -1,457 +0,0 @@ ----------------------------------------------------------------------------------- --- Company: --- Engineer: --- --- Create Date: 11/06/2012 03:04:35 PM --- Design Name: --- Module Name: wb_ddr_ctrl_wb_sc_fe - Behavioral --- Project Name: --- Target Devices: --- Tool Versions: --- Description: Memory controller - system clock domain - Cache front-end - --- Data path --- --- 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; - -use work.intercon_package.all; - --- control slave port register map --- 0: 0 - invalidate --- write '1' to invalidate entire cache --- 1 - flush --- write '1' to flush all dirty lines --- 31..2 - reserved --- 1: reserved --- --- When both flush and invalidate are set at the same time, the entire cache is --- invalidated, with all dirty lines being written back to memory before --- invalidation. - -entity wb_ddr_ctrl_wb_sc_fe is - generic ( - line_size : integer := 8; - lines : integer := 64; - assoc : integer := 2; - line_size_ln2 : integer := 3; - lines_ln2 : integer := 6; - assoc_ln2 : integer := 1; - addr_width : integer := 23; - dontcare : std_logic := '-' - ); - port ( - -- Wishbone slave - clk_i : in std_logic; - rst_i : in std_logic; - 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; - - -- To backend - 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(63 downto 0); - mem_ack : in std_logic; - mem_dat_i : in std_logic_vector(63 downto 0) - ); -end wb_ddr_ctrl_wb_sc_fe; - -architecture Behavioral of wb_ddr_ctrl_wb_sc_fe is - attribute ram_style : string; - attribute priority_extract : string; - - component wb_ddr_ctrl_wb_sc_fe_fsm - generic ( - line_size : integer; - lines : integer; - assoc : integer; - line_size_ln2 : integer; - lines_ln2 : integer; - assoc_ln2 : integer; - addr_width : integer); - port ( - clk_i : in std_logic; - rst_i : in std_logic; - cyc_i : in std_logic; - stb_i : in std_logic; - we_i : in std_logic; - adr_tag_eq : in std_logic_vector(assoc-1 downto 0); - eject_dirty : in std_logic; - mem_offset : in unsigned(line_size_ln2-1 downto 0); - mfi_index : in unsigned(lines_ln2-assoc_ln2-1 downto 0); - user_cc_req_flush : in std_logic; - user_cc_req_inval : in std_logic; - user_cc_req_none : in std_logic; - adr_tag_eq_num_dirty : in std_logic; - mem_ack : in std_logic; - mfi_num_dirty : in std_logic; - cc_valid : in std_logic_vector(assoc-1 downto 0); - cc_dirty : in std_logic_vector(assoc-1 downto 0); - ack_o : out std_logic; - update_lru : out std_logic := '0'; - set_clean : out std_logic := '0'; - set_dirty : out std_logic := '0'; - set_valid : out std_logic := '0'; - set_invalid : out std_logic := '0'; - cache_write : out std_logic := '0'; - cache_from_mem : out std_logic := '0'; - cache_to_mem : out std_logic := '0'; - mem_rdrq : out std_logic := '0'; - mem_wrrq : out std_logic := '0'; - mfi : out std_logic := '0'; - user_cc_ack_o : 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); - constant index_width : integer := lines_ln2-assoc_ln2; - constant offset_width : integer := line_size_ln2; - - -- Cache control signals / memory - subtype tag_t is std_logic_vector(assoc*tag_width-1 downto 0); - subtype lru_t is unsigned(assoc*assoc_ln2-1 downto 0); - type cc_tag_a is array(lines/assoc-1 downto 0) of tag_t; - type cc_lru_a is array(lines/assoc-1 downto 0) of lru_t; - type cc_valid_a is array(lines/assoc-1 downto 0) of std_logic_vector(assoc-1 downto 0); - type cc_dirty_a is array(lines/assoc-1 downto 0) of std_logic_vector(assoc-1 downto 0); - signal cc_tag : cc_tag_a := (others => (others => dontcare)); - signal cc_lru : cc_lru_a := (others => (others => dontcare)); - signal cc_valid : cc_valid_a := (others => (others => '0')); - signal cc_dirty : cc_dirty_a := (others => (others => dontcare)); - attribute ram_style of cc_tag : signal is "block"; - attribute ram_style of cc_lru : signal is "distributed"; - attribute ram_style of cc_valid : signal is "distributed"; - attribute ram_style of cc_dirty : signal is "distributed"; - signal cc_we : std_logic := '0'; - signal cc_wr_addr, cc_rd_addr : unsigned(lines_ln2-assoc_ln2-1 downto 0) := (others => dontcare); - signal cc_tag_wr_data, cc_tag_rd_data : tag_t := (others => dontcare); - signal cc_lru_wr_data, cc_lru_rd_data : lru_t := (others => dontcare); - signal cc_valid_wr_data, cc_valid_rd_data : std_logic_vector(assoc-1 downto 0) := (others => '0'); - signal cc_dirty_wr_data, cc_dirty_rd_data : std_logic_vector(assoc-1 downto 0) := (others => dontcare); - - -- Convenience variable for cc_tag_rd_data - type tag_a is array(assoc-1 downto 0) of std_logic_vector(tag_width-1 downto 0); - signal tags : tag_a := (others => (others => dontcare)); - - -- Cache data signals / memory - -- 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 => dontcare); - signal cache_bwe : std_logic_vector(7 downto 0) := (others => dontcare); - - - -- Convenience variables for adr_i - signal adr_index : unsigned(index_width-1 downto 0); - signal adr_offset : unsigned(offset_width-1 downto 0); - signal adr_tag : std_logic_vector(tag_width-1 downto 0); - - -- Tag comparator output - signal adr_tag_eq : std_logic_vector(assoc-1 downto 0); - - -- LRU comparator output - signal lru_eq0 : std_logic_vector(assoc-1 downto 0); - - -- Priority encoders - signal adr_tag_eq_num, eject_num : unsigned(assoc_ln2-1 downto 0); - attribute priority_extract of adr_tag_eq_num : signal is "yes"; - attribute priority_extract of eject_num : signal is "yes"; - - -- control signals - signal update_lru, set_dirty, set_valid, cache_write, cache_from_mem, eject_dirty : std_logic; - signal set_invalid, set_clean, cache_to_mem, adr_tag_eq_num_dirty : std_logic; - signal mem_offset, mem_offset_dly : unsigned(offset_width-1 downto 0); - signal mem_rdrq_int, mem_wrrq_int : std_logic; - - -- Manual flush/invalidate control signals - signal mfi : std_logic; - signal mfi_index : unsigned(lines_ln2-assoc_ln2-1 downto 0); - signal mfi_num : unsigned(assoc_ln2-1 downto 0); - signal mfi_index_ctr_en, mfi_num_ctr_en : std_logic; - signal mfi_num_dirty : std_logic; - signal user_cc_req_flush, user_cc_req_inval, user_cc_req_none : 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 when mem_ack = '1' and mfi = '0'else - adr_index & eject_num & mem_offset_dly when mfi = '0' else - mfi_index & eject_num & mem_offset when mem_ack = '1' and mfi = '1'else - mfi_index & eject_num & mem_offset_dly; -- when mfi = '1'; - cache_wr_addr <= adr_index & adr_tag_eq_num & adr_offset when cache_from_mem = '0' else - adr_index & eject_num & mem_offset; - 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 => dontcare); - cache_bwe <= "0000" & wbs_i.sel_i when cache_write = '1' and wbs_i.adr_i(2) = '0' else - wbs_i.sel_i & "0000" when cache_write = '1' and wbs_i.adr_i(2) = '1' else - "11111111" when cache_from_mem = '1' and mem_ack = '1' else - "00000000"; - - 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); - mem_dat_o <= cache_rd_data; - - mem_adr <= adr_tag & std_logic_vector(adr_index) when cache_from_mem = '1' else - tags(to_integer(eject_num)) & std_logic_vector(adr_index) when cache_to_mem = '1' and mfi = '0' else - tags(to_integer(eject_num)) & std_logic_vector(mfi_index); -- when cache_to_mem = '1' and mfi = '1' - - cc_wr_data_gen : for i in 0 to assoc-1 generate - cc_tag_wr_data((i+1)*tag_width-1 downto i*tag_width) <= - adr_tag when eject_num = i and set_valid = '1' else - cc_tag_rd_data((i+1)*tag_width-1 downto i*tag_width); - - cc_lru_wr_data((i+1)*assoc_ln2-1 downto assoc_ln2*i) <= - to_unsigned(assoc-1,assoc_ln2) when adr_tag_eq(i) = '1' and update_lru = '1' else - cc_lru_rd_data((i+1)*assoc_ln2-1 downto assoc_ln2*i) when cc_lru_rd_data((i+1)*assoc_ln2-1 downto assoc_ln2*i) = 0 else - cc_lru_rd_data((i+1)*assoc_ln2-1 downto assoc_ln2*i)-1 when update_lru = '1' else - cc_lru_rd_data((i+1)*assoc_ln2-1 downto assoc_ln2*i); - - cc_valid_wr_data(i) <= - '1' when eject_num = i and set_valid = '1' else - '0' when (adr_tag_eq(i) = '1' or mfi = '1') and set_invalid = '1' else - cc_valid_rd_data(i); - - cc_dirty_wr_data(i) <= - '1' when adr_tag_eq(i) = '1' and set_dirty = '1' else - '0' when eject_num = i and set_valid = '1' else - '0' when mfi_num = i and set_clean = '1' else - cc_dirty_rd_data(i); - end generate; - - cc_wr_addr <= mfi_index when mfi = '1' else - adr_index;-- when update_lru = '1' or set_dirty = '1' or set_valid = '1' or set_invalid = '1' else - --(others => dontcare); - cc_we <= update_lru or set_dirty or set_valid or set_invalid or set_clean; - - -- Memory for cache control - cc_mem : process(clk_i) - variable cc_wr_addr_int : integer range 0 to lines/assoc-1; - variable cc_rd_addr_int : integer range 0 to lines/assoc-1; - begin - if falling_edge(clk_i) then - cc_wr_addr_int := to_integer(cc_wr_addr); - cc_rd_addr_int := to_integer(cc_rd_addr); - if cc_we = '1' then - cc_tag(cc_wr_addr_int) <= cc_tag_wr_data; - cc_lru(cc_wr_addr_int) <= cc_lru_wr_data; - cc_valid(cc_wr_addr_int) <= cc_valid_wr_data; - cc_dirty(cc_wr_addr_int) <= cc_dirty_wr_data; - end if; - cc_tag_rd_data <= cc_tag(cc_rd_addr_int); - cc_lru_rd_data <= cc_lru(cc_rd_addr_int); - cc_valid_rd_data <= cc_valid(cc_rd_addr_int); - cc_dirty_rd_data <= cc_dirty(cc_rd_addr_int); - end if; - end process cc_mem; - - 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_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 - unsigned(wbs_i.adr_i(offset_width+2 downto 3)); - adr_tag <= --wbs_cc_i.dat_i(addr_width+2 downto offset_width+index_width+3) when user_cc = '1' else - wbs_i.adr_i(addr_width+2 downto offset_width+index_width+3); - - tags_gen : for i in 0 to assoc-1 generate - tags(i) <= cc_tag_rd_data((i+1)*tag_width-1 downto i*tag_width); - end generate; - - cc_rd_addr <= mfi_index when mfi = '1' else - adr_index; - - tag_compare : for i in 0 to assoc-1 generate - adr_tag_eq(i) <= cc_valid_rd_data(i) when tags(i) = adr_tag else - '0'; - end generate; - - lru_compare : for i in 0 to assoc-1 generate - lru_eq0(i) <= '1' when cc_lru_rd_data((i+1)*assoc_ln2-1 downto assoc_ln2*i) = 0 else - '1' when cc_valid_rd_data(i) = '0' else - '0'; - end generate; - - -- The comb. process for..loop version does not synthesize properly, so do - -- this manually - assert assoc = 2 or assoc = 4 report "Unsupported associativity" severity error; - pe_assoc_2 : if assoc = 2 generate - adr_tag_eq_num <= to_unsigned(0,1) when adr_tag_eq(0) = '1' else - to_unsigned(1,1) when adr_tag_eq(1) = '1' else - (others => dontcare); - eject_num <= mfi_num when mfi = '1' else - to_unsigned(0,1) when lru_eq0(0) = '1' else - to_unsigned(1,1) when lru_eq0(1) = '1' else - to_unsigned(0,1); - end generate; - pe_assoc_4 : if assoc = 4 generate - adr_tag_eq_num <= to_unsigned(0,2) when adr_tag_eq(0) = '1' else - to_unsigned(1,2) when adr_tag_eq(1) = '1' else - to_unsigned(2,2) when adr_tag_eq(2) = '1' else - to_unsigned(3,2) when adr_tag_eq(3) = '1' else - (others => dontcare); - eject_num <= mfi_num when mfi = '1' else - to_unsigned(0,2) when lru_eq0(0) = '1' else - to_unsigned(1,2) when lru_eq0(1) = '1' else - to_unsigned(2,2) when lru_eq0(2) = '1' else - to_unsigned(3,2) when lru_eq0(3) = '1' else - to_unsigned(0,1); - end generate; - - adr_tag_eq_num_dirty <= cc_dirty_rd_data(to_integer(adr_tag_eq_num)) and cc_valid_rd_data(to_integer(adr_tag_eq_num)); - mfi_num_dirty <= cc_dirty_rd_data(to_integer(mfi_num)) and cc_valid_rd_data(to_integer(mfi_num)); - eject_dirty <= cc_dirty_rd_data(to_integer(eject_num)) and cc_valid_rd_data(to_integer(eject_num)); - - -- Offset counter - mem_offset_ctr : process(clk_i) - 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; - - mfi_index_ctr_en <= '1' when ((user_cc_req_flush = '0' or to_integer(unsigned(cc_valid_rd_data and cc_dirty_rd_data)) = 0) and - (user_cc_req_inval = '0' or to_integer(unsigned(cc_valid_rd_data)) = 0)) else - '0'; - - mfi_index_ctr : process(clk_i) - begin - if rising_edge(clk_i) then - if mfi = '0' then - mfi_index <= to_unsigned(0, lines_ln2-assoc_ln2); - elsif mfi_index_ctr_en = '1' then - mfi_index <= mfi_index + 1; - end if; - end if; - end process mfi_index_ctr; - - mfi_num_ctr_en <= '1' when user_cc_req_flush = '1' and mfi_num_dirty = '0' else - '0'; - - mfi_num_ctr : process(clk_i) - begin - if rising_edge(clk_i) then - if mfi = '0' or mfi_index_ctr_en = '1' then - mfi_num <= to_unsigned(0, assoc_ln2); - elsif mfi_num_ctr_en = '1' then - mfi_num <= mfi_num + 1; - end if; - end if; - end process mfi_num_ctr; - - wb_ddr_ctrl_wb_sc_fe_fsm_inst: wb_ddr_ctrl_wb_sc_fe_fsm - generic map ( - line_size => line_size, - lines => lines, - assoc => assoc, - line_size_ln2 => line_size_ln2, - lines_ln2 => lines_ln2, - assoc_ln2 => assoc_ln2, - addr_width => addr_width) - port map ( - clk_i => clk_i, - rst_i => rst_i, - cyc_i => wbs_i.cyc_i, - stb_i => wbs_i.stb_i, - we_i => wbs_i.we_i, - adr_tag_eq => adr_tag_eq, - eject_dirty => eject_dirty, - mem_offset => mem_offset_dly, - mfi_index => mfi_index, - user_cc_req_flush => user_cc_req_flush, - user_cc_req_inval => user_cc_req_inval, - user_cc_req_none => user_cc_req_none, - adr_tag_eq_num_dirty => adr_tag_eq_num_dirty, - mem_ack => mem_ack, - mfi_num_dirty => mfi_num_dirty, - cc_valid => cc_valid_rd_data, - cc_dirty => cc_dirty_rd_data, - - ack_o => wbs_o.ack_o, - update_lru => update_lru, - set_clean => set_clean, - set_dirty => set_dirty, - set_valid => set_valid, - set_invalid => set_invalid, - cache_write => cache_write, - cache_from_mem => cache_from_mem, - cache_to_mem => cache_to_mem, - mem_rdrq => mem_rdrq_int, - mem_wrrq => mem_wrrq_int, - mfi => mfi, - user_cc_ack_o => wbs_cc_o.ack_o); - - mem_rdrq <= mem_rdrq_int; - mem_wrrq <= mem_wrrq_int; - - user_cc_req_flush <= - wbs_cc_i.dat_i(1) when (wbs_cc_i.cyc_i = '1' and wbs_cc_i.stb_i = '1' and - wbs_cc_i.we_i = '1') else - '0'; - user_cc_req_inval <= - wbs_cc_i.dat_i(0) when (wbs_cc_i.cyc_i = '1' and wbs_cc_i.stb_i = '1' and - wbs_cc_i.we_i = '1') else - '0'; - user_cc_req_none <= - '1' when (wbs_cc_i.cyc_i = '1' and wbs_cc_i.stb_i = '1' and - (wbs_cc_i.we_i = '0' or wbs_cc_i.dat_i(1 downto 0) = "00")) else - '0'; - - - wbs_cc_o.dat_o <= (others => '0'); -end Behavioral; diff --git a/src/wb_ddr_ctrl_wb_sc_fe_fsm.vhd b/src/wb_ddr_ctrl_wb_sc_fe_fsm.vhd deleted file mode 100644 index 9ed33c4..0000000 --- a/src/wb_ddr_ctrl_wb_sc_fe_fsm.vhd +++ /dev/null @@ -1,374 +0,0 @@ ----------------------------------------------------------------------------------- --- Company: --- Engineer: --- --- Create Date: 11/06/2012 03:04:35 PM --- Design Name: --- Module Name: wb_ddr_ctrl_wb_sc_fe_fsm - Behavioral --- Project Name: --- Target Devices: --- Tool Versions: --- Description: Memory controller - system clock domain - Cache front-end - --- Control path --- --- 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; - -use work.intercon_package.all; - -entity wb_ddr_ctrl_wb_sc_fe_fsm is - generic ( - line_size : integer := 16; - lines : integer := 64; - assoc : integer := 2; - line_size_ln2 : integer := 4; - lines_ln2 : integer := 6; - assoc_ln2 : integer := 1; - addr_width : integer := 24 - ); - port ( - clk_i : in std_logic; - rst_i : in std_logic; - - cyc_i : in std_logic; - stb_i : in std_logic; - we_i : in std_logic; - adr_tag_eq : in std_logic_vector(assoc-1 downto 0); - eject_dirty : in std_logic; - mem_offset : in unsigned(line_size_ln2-1 downto 0); - mfi_index : in unsigned(lines_ln2-assoc_ln2-1 downto 0); - adr_tag_eq_num_dirty : in std_logic; - user_cc_req_flush : in std_logic; - user_cc_req_inval : in std_logic; - user_cc_req_none : in std_logic; - mem_ack : in std_logic; - mfi_num_dirty : in std_logic; - cc_valid : in std_logic_vector(assoc-1 downto 0); - cc_dirty : in std_logic_vector(assoc-1 downto 0); - - ack_o : out std_logic; - update_lru : out std_logic := '0'; - set_dirty : out std_logic := '0'; - set_clean : out std_logic := '0'; - set_valid : out std_logic := '0'; - set_invalid : out std_logic := '0'; - cache_write : out std_logic := '0'; - cache_from_mem : out std_logic := '0'; - cache_to_mem : out std_logic := '0'; - mem_rdrq : out std_logic := '0'; - mem_wrrq : out std_logic := '0'; - mfi : out std_logic := '0'; - user_cc_ack_o : out std_logic := '0' - ); -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_WRITEBACK1, S_WRITEBACK2, S_FETCH1, S_FETCH2, S_WAIT, S_WAIT_FETCH, - S_MFI, S_MFI_WRITEBACK1, S_MFI_WRITEBACK2, S_MFI_WAIT); - signal state : states := S_IDLE; -begin - - cache_ctrl : process(clk_i) - begin - if rising_edge(clk_i) then - ack_o <= '0'; - update_lru <= '0'; - set_dirty <= '0'; - set_clean <= '0'; - set_valid <= '0'; - set_invalid <= '0'; - cache_write <= '0'; - cache_from_mem <= '0'; - cache_to_mem <= '0'; - mem_rdrq <= '0'; - mem_wrrq <= '0'; - mfi <= '0'; - user_cc_ack_o <= '0'; - - case state is - when S_IDLE => - if user_cc_req_flush = '1' or user_cc_req_inval = '1' then - mfi <= '1'; - state <= S_MFI; - elsif user_cc_req_none = '1' then - user_cc_ack_o <= '1'; - state <= S_WAIT; - elsif cyc_i = '1' and stb_i = '1' then - if we_i = '1' then - if to_integer(unsigned(adr_tag_eq)) = 0 then - -- miss - if eject_dirty = '1' then - cache_to_mem <= '1'; - mem_wrrq <= '1'; - state <= S_WRITEBACK1; - else - cache_from_mem <= '1'; - mem_rdrq <= '1'; - state <= S_FETCH1; - end if; - else - -- hit - ack_o <= '1'; - update_lru <= '1'; - set_dirty <= '1'; - cache_write <= '1'; - state <= S_WAIT; - end if; - else - if to_integer(unsigned(adr_tag_eq)) = 0 then - -- miss - if eject_dirty = '1' then - cache_to_mem <= '1'; - mem_wrrq <= '1'; - state <= S_WRITEBACK1; - else - cache_from_mem <= '1'; - mem_rdrq <= '1'; - state <= S_FETCH1; - end if; - else - -- hit - ack_o <= '1'; - update_lru <= '1'; - state <= S_WAIT; - end if; - end if; - end if; - when S_WAIT => - state <= S_IDLE; - 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_WRITEBACK1 => - cache_to_mem <= '1'; - 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_FETCH1; - when S_MFI => - mfi <= '1'; - if ((user_cc_req_flush = '0' or to_integer(unsigned(cc_valid and cc_dirty)) = 0) and - (user_cc_req_inval = '0' or to_integer(unsigned(cc_valid)) = 0)) then - -- nothing to do for this set or done with it - if mfi_index = lines/assoc-1 then - user_cc_ack_o <= '1'; - state <= S_WAIT; - end if; - else - if user_cc_req_flush = '1' and to_integer(unsigned(cc_valid and cc_dirty)) /= 0 then - if mfi_num_dirty = '1' then - cache_to_mem <= '1'; - mem_wrrq <= '1'; - state <= S_MFI_WRITEBACK1; - end if; - elsif user_cc_req_inval = '1' then - set_invalid <= '1'; - end if; - end if; - - --if user_cc_req_inval = '1' then - -- if to_integer(unsigned(adr_tag_eq)) = 0 then - -- -- address not in cache, nothing to invalidate - -- user_cc_ack_o <= '1'; - -- state <= S_WAIT; - -- else - -- if adr_tag_eq_num_dirty = '1' then - -- -- line is dirty, flush first - -- cache_to_mem <= '1'; - -- mem_wrrq <= '1'; - -- state <= S_USER_WRITEBACK1; - -- else - -- set_invalid <= '1'; - -- user_cc_ack_o <= '1'; - -- state <= S_WAIT; - -- end if; - -- end if; - --elsif user_cc_req_flush = '1' then - -- if to_integer(unsigned(adr_tag_eq)) = 0 or adr_tag_eq_num_dirty = '0' then - -- -- address not in cache or clean, nothing to flush - -- user_cc_ack_o <= '1'; - -- state <= S_WAIT; - -- else - -- cache_to_mem <= '1'; - -- mem_wrrq <= '1'; - -- state <= S_USER_WRITEBACK1; - -- end if; - --else -- WTF? - -- state <= S_WAIT; - --end if; - when S_MFI_WRITEBACK1 => - mfi <= '1'; - cache_to_mem <= '1'; - state <= S_MFI_WRITEBACK2; - when S_MFI_WRITEBACK2 => - mfi <= '1'; - cache_to_mem <= '1'; - if mem_offset = line_size-1 and mem_ack = '1' then - cache_to_mem <= '0'; - set_clean <= '1'; - state <= S_MFI_WAIT; - end if; - when S_MFI_WAIT => - mfi <= '1'; - state <= S_MFI; - end case; - end if; - end process cache_ctrl; - - --cache_ctrl : process(clk_i) - -- begin - -- if rising_edge(clk_i) then - -- cache_we <= '0'; - -- cache_wr_data <= (others => '-'); - -- line_info_we <= '0'; - -- line_info_wr_data <= dontcare_line_info; - -- mem_adr <= (others => '-'); - -- mem_rdrq <= '0'; - -- mem_wrrq <= '0'; - - -- case state is - -- when S_IDLE => - -- if wbs_i.stb_i = '1' and wbs_i.cyc_i = '1' then - -- if wbs_i.we_i = '1' then - -- if to_integer(unsigned(adr_tag_eq)) = 0 then - -- -- miss - -- if line_info_rd_data.valid(eject_num) = '1' and - -- line_info_rd_data.dirty(eject_num) = '1' then - -- cache_rd_addr <= adr_index*line_size*assoc+eject_num*line_size+0; - -- ctr <= 0; - -- state <= S_WRITEBACK1; - -- else - -- mem_adr <= wbs_i.adr_i(addr_width+1 downto line_size_ln2+2); - -- mem_rdrq <= '1'; - -- ctr <= 0; - -- state <= S_FETCH; - -- end if; - -- else - -- -- hit - -- wbs_o.ack_o <= '1'; - -- cache_wr_data <= wbs_i.dat_i; - -- cache_wr_addr <= adr_index*line_size*assoc+adr_tag_eq_num*line_size+adr_offset; - -- cache_we <= '1'; - -- line_info_wr_data <= line_info_rd_data; - -- line_info_wr_data.dirty(adr_tag_eq_num) <= '1'; - -- for i in 0 to assoc-1 loop - -- if i = adr_tag_eq_num then - -- line_info_wr_data.lru(i) <= assoc-1; - -- else - -- if line_info_rd_data.lru(i) > 0 then - -- line_info_wr_data.lru(i) <= line_info_rd_data.lru(i) - 1; - -- end if; - -- end if; - -- end loop; - -- line_info_wr_addr <= line_info_rd_addr; - -- line_info_we <= '1'; - -- state <= S_WAIT; - -- end if; - -- else - -- if to_integer(unsigned(adr_tag_eq)) = 0 then - -- -- miss - -- if line_info_rd_data.valid(eject_num) = '1' and - -- line_info_rd_data.dirty(eject_num) = '1' then - -- cache_rd_addr <= adr_index*line_size*assoc+eject_num*line_size+0; - -- ctr <= 0; - -- state <= S_WRITEBACK1; - -- else - -- mem_adr <= wbs_i.adr_i(addr_width+1 downto line_size_ln2+2); - -- mem_rdrq <= '1'; - -- ctr <= 0; - -- state <= S_FETCH; - -- end if; - -- else - -- -- hit - -- cache_rd_addr <= adr_index*line_size*assoc+adr_tag_eq_num*line_size+adr_offset; - -- line_info_wr_data <= line_info_rd_data; - -- for i in 0 to assoc-1 loop - -- if i = adr_tag_eq_num then - -- line_info_wr_data.lru(i) <= assoc-1; - -- else - -- if line_info_rd_data.lru(i) > 0 then - -- line_info_wr_data.lru(i) <= line_info_rd_data.lru(i) - 1; - -- end if; - -- end if; - -- end loop; - -- line_info_wr_addr <= line_info_rd_addr; - -- line_info_we <= '1'; - -- state <= S_READHIT; - -- end if; - -- end if; - -- end if; - -- when S_WAIT => - -- state <= S_IDLE; - -- when S_READHIT => - -- wbs_o.ack_o <= '1'; - -- state <= S_WAIT; - - -- when S_FETCH => - -- if mem_ack = '1' then - -- cache_wr_data <= mem_dat_i; - -- cache_wr_addr <= adr_index*line_size*assoc+eject_num*line_size+ctr; - -- cache_we <= '1'; - -- if ctr = line_size-1 then - -- line_info_wr_data <= line_info_rd_data; - -- line_info_wr_data.valid(eject_num) <= '1'; - -- line_info_wr_data.dirty(eject_num) <= '0'; - -- line_info_wr_data.tag(eject_num) <= adr_tag; - -- line_info_wr_addr <= line_info_rd_addr; - -- line_info_we <= '1'; - -- state <= S_IDLE; -- restart request - -- else - -- ctr <= ctr + 1; - -- end if; - -- end if; - -- when S_WRITEBACK1 => - -- mem_adr <= wbs_i.adr_i(addr_width+1 downto line_size_ln2+2); - -- mem_wrrq <= '1'; - -- state <= S_WRITEBACK2; - -- when S_WRITEBACK2 => - -- if mem_ack = '1' then - -- cache_rd_addr <= adr_index*line_size*assoc+eject_num*line_size+ctr; - -- if ctr = line_size-1 then - -- mem_adr <= wbs_i.adr_i(addr_width+1 downto line_size_ln2+2); - -- mem_rdrq <= '1'; - -- ctr <= 0; - -- state <= S_FETCH; - -- else - -- ctr <= ctr + 1; - -- end if; - -- end if; - -- end case; - -- end if; - -- end process cache_ctrl; -end Behavioral; - diff --git a/src/wb_ddr_ctrl_wb_sc_fe_ram.vhd b/src/wb_ddr_ctrl_wb_sc_fe_ram.vhd deleted file mode 100644 index 6690ff0..0000000 --- a/src/wb_ddr_ctrl_wb_sc_fe_ram.vhd +++ /dev/null @@ -1,143 +0,0 @@ ----------------------------------------------------------------------------------- --- 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/src/wb_mem_bridge.vhd b/src/wb_mem_bridge.vhd new file mode 100644 index 0000000..d489556 --- /dev/null +++ b/src/wb_mem_bridge.vhd @@ -0,0 +1,196 @@ +------------------------------------------------------------------------------- +-- Title : Wishbone <-> Memory controller bridge +-- Project : +------------------------------------------------------------------------------- +-- File : wb_mem_bridge.vhd +-- Author : Metthias Blankertz +-- Company : +-- Created : 2013-06-04 +-- Last update: 2013-06-04 +-- Platform : +-- Standard : VHDL'93/02 +------------------------------------------------------------------------------- +-- Description: +------------------------------------------------------------------------------- +-- Copyright (c) 2013 +------------------------------------------------------------------------------- +-- Revisions : +-- Date Version Author Description +-- 2013-06-04 1.0 matthias Created +------------------------------------------------------------------------------- + +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; + +use work.intercon_package.all; + +entity wb_mem_bridge is + generic ( + burst_length : integer := 8; + burst_length_ln2 : integer := 3; + dontcare : std_logic := '-' + ); + port ( + clk_i : in std_ulogic; + rst_i : in std_ulogic; + + wbs_i : in mem_bridge_wbs_i_type; + wbs_o : out mem_bridge_wbs_o_type; + + wb_mem_rdrq : out std_logic; + wb_mem_wrrq : out std_logic; + wb_mem_adr : out std_logic_vector(19 downto 0); + wb_mem_dat_o : out std_logic_vector(63 downto 0); + wb_mem_sel : out std_logic_vector(7 downto 0); + wb_mem_ack : in std_logic; + wb_mem_dat_i : in std_logic_vector(63 downto 0) + ); +end wb_mem_bridge; + +architecture Behavioral of wb_mem_bridge is + signal buf_dirty : std_logic_vector(burst_length*8-1 downto 0) := (others => '0'); + signal buf_valid : std_logic := '0'; + signal buf_tag : std_logic_vector(wbs_i.adr_i'left downto burst_length_ln2+3); + signal buf_adr : std_logic_vector(2 downto 0); + signal buf_bwe : std_logic_vector(7 downto 0) := (others => '0'); + signal buf_hit : std_logic; + signal buf_dat_o, buf_dat_i : std_logic_vector(63 downto 0); + + signal wb_in_cyc, write_flush, read_fill, buf_wbwr : std_logic := '0'; + signal ctr : unsigned(burst_length_ln2-1 downto 0) := to_unsigned(0, burst_length_ln2); +begin + + buf_hit <= '1' when wbs_i.adr_i(wbs_i.adr_i'left downto burst_length_ln2+3) = buf_tag else + '0'; + + buf_bwe <= "0000" & wbs_i.sel_i when buf_wbwr = '1' and wbs_i.adr_i(2) = '0' else + wbs_i.sel_i & "0000" when buf_wbwr = '1' and wbs_i.adr_i(2) = '1' else + "11111111" when read_fill = '1' and wb_mem_ack = '1' else + "00000000"; + buf_adr <= std_logic_vector(ctr+1) when write_flush = '1' and wb_mem_ack = '1' else + std_logic_vector(ctr) when write_flush = '1' or read_fill = '1' else + wbs_i.adr_i(burst_length_ln2+2 downto 3); + buf_dat_i <= wb_mem_dat_i when read_fill = '1' else + wbs_i.dat_i & wbs_i.dat_i; + + buf : entity work.ram_16x64 + port map ( + clk => clk_i, + bwe => buf_bwe, + adr(3) => '0', + adr(2 downto 0) => buf_adr, + din => buf_dat_i, + dout => buf_dat_o + ); + + wbs_o.dat_o <= buf_dat_o(31 downto 0) when wbs_i.adr_i(2) = '0' else + buf_dat_o(63 downto 32); + + wb_mem_dat_o <= buf_dat_o; + wb_mem_sel <= buf_dirty(8*to_integer(ctr)+7 downto 8*to_integer(ctr)); + + + ctrl : process(clk_i) + begin + if rising_edge(clk_i) then + wb_mem_adr <= (others => dontcare); + wb_mem_wrrq <= '0'; + wb_mem_rdrq <= '0'; + buf_wbwr <= '0'; + if rst_i = '1' then + buf_dirty <= (others => '0'); + buf_valid <= '0'; + wbs_o.ack_o <= '0'; + wb_in_cyc <= '0'; + write_flush <= '0'; + read_fill <= '0'; + else + if write_flush = '1' then + if wb_mem_ack = '1' then + if ctr < burst_length-1 then + ctr <= ctr + 1; + else + -- Flush complete + buf_dirty <= (others => '0'); + write_flush <= '0'; + end if; + end if; + elsif read_fill = '1' then + if wb_mem_ack = '1' then + if ctr < burst_length-1 then + ctr <= ctr + 1; + else + -- Fill complete, set valid and update tag + buf_valid <= '1'; + buf_tag <= wbs_i.adr_i(wbs_i.adr_i'left downto burst_length_ln2+3); + read_fill <= '0'; + end if; + end if; + elsif wb_in_cyc = '0' and wbs_i.stb_i = '1' and wbs_i.cyc_i = '1' then + -- Start new wishbone request + if wbs_i.we_i = '1' then + -- Write request + if buf_hit = '1' or unsigned(buf_dirty) = 0 then + -- Hit or buffer empty + -- Update tag + buf_tag <= wbs_i.adr_i(wbs_i.adr_i'left downto burst_length_ln2+3); + wbs_o.ack_o <= '1'; -- Acknowlege + buf_wbwr <= '1'; -- WB write data into write buffer + -- Update write buffer valid flags + buf_dirty(4*to_integer(unsigned(wbs_i.adr_i(burst_length_ln2+2 downto 2)))+3 downto + 4*to_integer(unsigned(wbs_i.adr_i(burst_length_ln2+2 downto 2)))) <= wbs_i.sel_i; + wb_in_cyc <= '1'; + if buf_hit = '0' then + -- We got here bc buffer was clean and we changed the tag + buf_valid <= '0'; -- Invalidate buffer for reads + end if; + else + -- Miss, must flush + write_flush <= '1'; + wb_mem_wrrq <= '1'; + wb_mem_adr <= buf_tag; + ctr <= to_unsigned(0, burst_length_ln2); + end if; + else + -- Read request + if buf_hit = '1' and buf_valid = '1' then + -- Hit + wbs_o.ack_o <= '1'; + wb_in_cyc <= '1'; + else + -- Miss + if unsigned(buf_dirty) = 0 then + -- Clean, no flush + -- Start fill from memory + read_fill <= '1'; + wb_mem_rdrq <= '1'; + wb_mem_adr <= wbs_i.adr_i(wbs_i.adr_i'left downto burst_length_ln2+3); + ctr <= to_unsigned(0, burst_length_ln2); + else + -- Dirty, flush first + write_flush <= '1'; + wb_mem_wrrq <= '1'; + wb_mem_adr <= buf_tag; + ctr <= to_unsigned(0, burst_length_ln2); + end if; + end if; + end if; + elsif wb_in_cyc = '1' and wbs_i.stb_i = '0' then + wbs_o.ack_o <= '0'; + wb_in_cyc <= '0'; + end if; + end if; + end if; + end process ctrl; +end Behavioral; + + diff --git a/src/wishbone.defines b/src/wishbone.defines deleted file mode 100644 index 3121e9a..0000000 --- a/src/wishbone.defines +++ /dev/null @@ -1,147 +0,0 @@ -# Generated by PERL program wishbone.pl. -# File used as input for wishbone arbiter generation -# Generated Thu Jun 24 14:29:34 2004 - -filename=wb_interconnect -intercon=intercon -syscon=syscon -target=xilinx -hdl=vhdl -signal_groups=1 -tga_bits=2 -tgc_bits=3 -tgd_bits=0 -rename_tga=bte -rename_tgc=cti -rename_tgd=tgd -classic=000 -endofburst=111 -dat_size=32 -adr_size=28 -mux_type=andor -interconnect=crossbarswitch - -# until we have a real second master, a dummy -# to workaround bugs in interconnect generator -master dummy - type=ro - lock_o=0 - tga_o=1 - tgc_o=1 - tgd_o=0 - err_i=0 - rty_i=0 - priority_sdram_ctrl=1 - priority_sdram_ctrl_cc=1 - priority_mblite_rom=1 - priority_ram=1 - priority_pio_led=1 - priority_uart=1 -end master dummy - -# system controller -master cpu - type=rw - lock_o=0 - tga_o=0 - tgc_o=0 - tgd_o=0 - err_i=0 - rty_i=0 - priority_sdram_ctrl=2 - priority_sdram_ctrl_cc=2 - priority_mblite_rom=2 - priority_ram=2 - priority_pio_led=2 - priority_uart=2 -end master cpu - -# Wishbone (secondary) read port on CPU instr. memory -slave mblite_rom - type=ro - adr_i_hi=11 - adr_i_lo=2 - tga_i=0 - tgc_i=0 - tgd_i=0 - lock_i=0 - err_o=0 - rty_o=0 - baseaddr=0x0000000 - size=0x1000 -end slave mblite_rom - -# Internal RAM -slave ram - type=rw - adr_i_hi=10 - adr_i_lo=2 - tga_i=0 - tgc_i=0 - tgd_i=0 - lock_i=0 - err_o=0 - rty_o=0 - baseadr=0x0001000 - size=0x800 -end slave ram - -# PIO for LEDs -slave pio_led - type=rw - adr_i_hi=1 - adr_i_lo=1 - tga_i=0 - tgc_i=0 - tgd_i=0 - lock_i=0 - err_o=0 - rty_o=0 - baseadr=0x0004000 - size=0x4 -end slave pio_led - -# UART -slave uart - type=rw - adr_i_hi=2 - adr_i_lo=2 - tga_i=0 - tgc_i=0 - tgd_i=0 - lock_i=0 - err_o=0 - rty_o=0 - baseadr=0x0004020 - size=0x8 -end slave uart - -# SDRAM controller Cache control port -slave sdram_ctrl_cc - type=rw - adr_i_hi=1 - adr_i_lo=1 - tga_i=1 - tgc_i=1 - tgd_i=0 - lock_i=0 - err_o=0 - rty_o=0 - baseadr=0x0004010 - size=0x4 -end slave sdram_ctrl_cc - -# SDRAM controller memory port -slave sdram_ctrl - type=rw - adr_i_hi=25 - adr_i_lo=2 - tga_i=0 - tgc_i=0 - tgd_i=0 - lock_i=0 - err_o=0 - rty_o=0 - baseadr=0x4000000 - size=0x4000000 -end slave sdram_ctrl diff --git a/src/wishbone.vhd b/src/wishbone.vhd new file mode 100644 index 0000000..c06aba8 --- /dev/null +++ b/src/wishbone.vhd @@ -0,0 +1,285 @@ +------------------------------------------------------------------------------- +-- Title : Wishbone interconnect +-- Project : +------------------------------------------------------------------------------- +-- File : wishbone.vhd +-- Author : Matthias Blankertz +-- Company : +-- Created : 2013-06-03 +-- Last update: 2013-06-04 +-- Platform : +-- Standard : VHDL'93/02 +------------------------------------------------------------------------------- +-- Description: +------------------------------------------------------------------------------- +-- Copyright (c) 2013 +------------------------------------------------------------------------------- +-- Revisions : +-- Date Version Author Description +-- 2013-06-03 1.0 matthias Created +------------------------------------------------------------------------------- + +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; + +package intercon_package is + + constant wb_addr_width : integer := 28; + + type cpu_wbm_i_type is record + dat_i : std_logic_vector(31 downto 0); + ack_i : std_logic; + end record; + type cpu_wbm_o_type is record + dat_o : std_logic_vector(31 downto 0); + we_o : std_logic; + sel_o : std_logic_vector(3 downto 0); + adr_o : std_logic_vector(wb_addr_width-1 downto 0); + cyc_o : std_logic; + stb_o : std_logic; + end record; + + type mblite_rom_wbs_i_type is record + sel_i : std_logic_vector(3 downto 0); + adr_i : std_logic_vector(11 downto 2); + cyc_i : std_logic; + stb_i : std_logic; + end record; + type mblite_rom_wbs_o_type is record + dat_o : std_logic_vector(31 downto 0); + ack_o : std_logic; + end record; + + type ram_wbs_i_type is record + dat_i : std_logic_vector(31 downto 0); + we_i : std_logic; + sel_i : std_logic_vector(3 downto 0); + adr_i : std_logic_vector(10 downto 2); + cyc_i : std_logic; + stb_i : std_logic; + end record; + type ram_wbs_o_type is record + dat_o : std_logic_vector(31 downto 0); + ack_o : std_logic; + end record; + + type pio_led_wbs_i_type is record + dat_i : std_logic_vector(31 downto 0); + we_i : std_logic; + sel_i : std_logic_vector(3 downto 0); + cyc_i : std_logic; + stb_i : std_logic; + end record; + type pio_led_wbs_o_type is record + dat_o : std_logic_vector(31 downto 0); + ack_o : std_logic; + end record; + + type uart_wbs_i_type is record + dat_i : std_logic_vector(7 downto 0); + we_i : std_logic; + adr_i : std_logic_vector(0 downto 0); + cyc_i : std_logic; + stb_i : std_logic; + end record; + type uart_wbs_o_type is record + dat_o : std_logic_vector(7 downto 0); + ack_o : std_logic; + end record; + + type mem_bridge_wbs_i_type is record + dat_i : std_logic_vector(31 downto 0); + we_i : std_logic; + sel_i : std_logic_vector(3 downto 0); + adr_i : std_logic_vector(25 downto 2); + cyc_i : std_logic; + stb_i : std_logic; + end record; + type mem_bridge_wbs_o_type is record + dat_o : std_logic_vector(31 downto 0); + ack_o : std_logic; + end record; + +end intercon_package; + +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; + +use work.intercon_package.all; + +entity interconnect is + port ( + -- wishbone master port(s) + -- cpu + cpu_wbm_i : out cpu_wbm_i_type; + cpu_wbm_o : in cpu_wbm_o_type; + + -- wishbone slave port(s) + -- mblite_rom + mblite_rom_wbs_i : out mblite_rom_wbs_i_type; + mblite_rom_wbs_o : in mblite_rom_wbs_o_type; + -- ram + ram_wbs_i : out ram_wbs_i_type; + ram_wbs_o : in ram_wbs_o_type; + -- pio_led + pio_led_wbs_i : out pio_led_wbs_i_type; + pio_led_wbs_o : in pio_led_wbs_o_type; + -- uart + uart_wbs_i : out uart_wbs_i_type; + uart_wbs_o : in uart_wbs_o_type; + -- sdram_ctrl + mem_bridge_wbs_i : out mem_bridge_wbs_i_type; + mem_bridge_wbs_o : in mem_bridge_wbs_o_type; + + -- clock and reset + clk : in std_logic; + reset : in std_logic + ); +end interconnect; + +architecture Behavioral of interconnect is + signal busm_dat_o, busm_dat_i : std_logic_vector(31 downto 0); + signal busm_adr_o : std_logic_vector(wb_addr_width-1 downto 0); + signal busm_stb_o, busm_cyc_o, busm_we_o, busm_ack_i : std_logic; + signal busm_sel_o : std_logic_vector(3 downto 0); + signal busm_bte_o : std_logic_vector(1 downto 0); + signal busm_cti_o : std_logic_vector(2 downto 0); + + signal buss_dat_o, buss_dat_i : std_logic_vector(31 downto 0); + signal buss_adr_o : std_logic_vector(wb_addr_width-1 downto 0); + signal buss_stb_o, buss_cyc_o, buss_we_o, buss_ack_i : std_logic; + signal buss_sel_o : std_logic_vector(3 downto 0); + signal buss_bte_o : std_logic_vector(1 downto 0); + signal buss_cti_o : std_logic_vector(2 downto 0); + + signal mblite_rom_ss, ram_ss, pio_led_ss, uart_ss, mem_bridge_ss : std_logic; + signal mblite_rom_ss_r, ram_ss_r, pio_led_ss_r, uart_ss_r, mem_bridge_ss_r : std_logic; + signal uart_cs : std_logic; + + signal byte_sel : integer range 0 to 3; + signal hword_sel : integer range 0 to 1; + +begin + -- Master arbiter (1 of n masters <-> busm) + -- Currently only 1 master, so direct connection + busm_dat_o <= cpu_wbm_o.dat_o; + busm_adr_o <= cpu_wbm_o.adr_o; + busm_stb_o <= cpu_wbm_o.stb_o; + busm_cyc_o <= cpu_wbm_o.cyc_o; + busm_we_o <= cpu_wbm_o.we_o; + busm_sel_o <= cpu_wbm_o.sel_o; + busm_bte_o <= "00"; + busm_cti_o <= "000"; + + cpu_wbm_i.dat_i <= busm_dat_i; + cpu_wbm_i.ack_i <= busm_ack_i; + + + -- Interconnect bus (Pipeline stage can be added here) + buss_dat_o <= busm_dat_o; + buss_adr_o <= busm_adr_o; + buss_stb_o <= busm_stb_o; + buss_cyc_o <= busm_cyc_o; + buss_we_o <= busm_we_o; + buss_sel_o <= busm_sel_o; + buss_bte_o <= busm_bte_o; + buss_cti_o <= buss_cti_o; + + busm_dat_i <= buss_dat_i; + busm_ack_i <= buss_ack_i; + + + -- Slave select gen + mblite_rom_ss <= '1' when unsigned(buss_adr_o((wb_addr_width-1) downto 12) & x"000") = 16#00000000# else '0'; + ram_ss <= '1' when unsigned(buss_adr_o((wb_addr_width-1) downto 11) & "00000000000") = 16#00001000# else '0'; + pio_led_ss <= '1' when unsigned(buss_adr_o((wb_addr_width-1) downto 2) & "00") = 16#00004000# else '0'; + uart_ss <= '1' when unsigned(buss_adr_o((wb_addr_width-1) downto 1) & "0") = 16#00004020# else '0'; + mem_bridge_ss <= '1' when unsigned(buss_adr_o((wb_addr_width-1) downto 26) & "00" & x"000000") = 16#08000000# else '0'; + + byte_sel <= to_integer(unsigned(buss_adr_o(1 downto 0))); + hword_sel <= to_integer(unsigned(buss_adr_o(1 downto 1))); + + -- It is assumed that all peripherals take at least 1 cycle until output + -- => We can register the slave selects for the bus multiplexer for better timing + ss_regs : process(clk) + begin + if rising_edge(clk) then + mblite_rom_ss_r <= mblite_rom_ss; + ram_ss_r <= ram_ss; + pio_led_ss_r <= pio_led_ss; + uart_ss_r <= uart_ss; + mem_bridge_ss_r <= mem_bridge_ss; + end if; + end process ss_regs; + + -- Slave -> Bus multiplexer + buss_dat_i <= mblite_rom_wbs_o.dat_o when mblite_rom_ss_r = '1' else + ram_wbs_o.dat_o when ram_ss_r = '1' else + pio_led_wbs_o.dat_o when pio_led_ss_r = '1' else + uart_wbs_o.dat_o & uart_wbs_o.dat_o & uart_wbs_o.dat_o & uart_wbs_o.dat_o when uart_ss_r = '1' else + mem_bridge_wbs_o.dat_o when mem_bridge_ss_r = '1' else + (others => '-'); + buss_ack_i <= mblite_rom_wbs_o.ack_o when mblite_rom_ss_r = '1' else + ram_wbs_o.ack_o when ram_ss_r = '1' else + pio_led_wbs_o.ack_o when pio_led_ss_r = '1' else + uart_wbs_o.ack_o when uart_ss_r = '1' else + mem_bridge_wbs_o.ack_o when mem_bridge_ss_r = '1' else + '0'; + + -- Slave modules + -- mblite_rom (32bit, 0x00000000 - 0x00001000) + mblite_rom_wbs_i.sel_i <= buss_sel_o; + mblite_rom_wbs_i.adr_i <= buss_adr_o(11 downto 2); + mblite_rom_wbs_i.cyc_i <= buss_cyc_o and mblite_rom_ss; + mblite_rom_wbs_i.stb_i <= buss_stb_o and mblite_rom_ss; + + -- ram (32bit, 0x00001000 - 0x00001800) + ram_wbs_i.sel_i <= buss_sel_o; + ram_wbs_i.adr_i <= buss_adr_o(10 downto 2); + ram_wbs_i.cyc_i <= buss_cyc_o and ram_ss; + ram_wbs_i.stb_i <= buss_stb_o and ram_ss; + ram_wbs_i.we_i <= buss_we_o; + ram_wbs_i.dat_i <= buss_dat_o; + + -- PIO led (32bit, 0x00004000 - 0x00004004) + pio_led_wbs_i.sel_i <= buss_sel_o; + pio_led_wbs_i.cyc_i <= buss_cyc_o and pio_led_ss; + pio_led_wbs_i.stb_i <= buss_stb_o and pio_led_ss; + pio_led_wbs_i.we_i <= buss_we_o; + pio_led_wbs_i.dat_i <= buss_dat_o; + + -- UART (8bit, 0x00004020 - 0x00004022) + uart_cs <= buss_sel_o(3-byte_sel); + uart_wbs_i.cyc_i <= buss_cyc_o and uart_ss; + uart_wbs_i.stb_i <= buss_stb_o and uart_ss and uart_cs; + uart_wbs_i.we_i <= buss_we_o; + uart_wbs_i.dat_i <= buss_dat_o(8*(3-byte_sel)+7 downto 8*(3-byte_sel)); + uart_wbs_i.adr_i <= buss_adr_o(0 downto 0); + + -- mem_bridge (32bit, 0x08000000 - 0x0C000000) + mem_bridge_wbs_i.sel_i <= buss_sel_o; + mem_bridge_wbs_i.adr_i <= buss_adr_o(25 downto 2); + mem_bridge_wbs_i.cyc_i <= buss_cyc_o and mem_bridge_ss; + mem_bridge_wbs_i.stb_i <= buss_stb_o and mem_bridge_ss; + mem_bridge_wbs_i.we_i <= buss_we_o; + mem_bridge_wbs_i.dat_i <= buss_dat_o; + +end Behavioral; diff --git a/tb/wb_ddr_ctrl_wb_sc_tb.vhd b/tb/wb_ddr_ctrl_wb_sc_tb.vhd index 8d82532..8c57560 100644 --- a/tb/wb_ddr_ctrl_wb_sc_tb.vhd +++ b/tb/wb_ddr_ctrl_wb_sc_tb.vhd @@ -6,7 +6,7 @@ -- Author : -- Company : -- Created : 2013-03-08 --- Last update: 2013-03-08 +-- Last update: 2013-06-04 -- Platform : -- Standard : VHDL'87 ------------------------------------------------------------------------------- @@ -26,7 +26,6 @@ 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 @@ -37,33 +36,6 @@ 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; @@ -72,14 +44,17 @@ architecture testbench of wb_ddr_ctrl_wb_sc_tb is -- 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 wb_mem_rdrq : std_logic := '0'; + signal wb_mem_wrrq : std_logic := '0'; + signal wb_mem_adr : std_logic_vector(19 downto 0); + signal wb_mem_dat_o : std_logic_vector(63 downto 0); + signal wb_mem_sel : std_logic_vector(7 downto 0); + signal wb_mem_ack : std_logic; + signal wb_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); @@ -93,7 +68,7 @@ architecture testbench of wb_ddr_ctrl_wb_sc_tb is signal sim_done : boolean := false; constant maxdelay : integer := 8; signal delay : integer range 0 to maxdelay := 2; - signal readrate : integer := 0; + signal readrate : integer := 1; type fifo_a is array(0 to 127) of std_logic_vector(22 downto 0); signal fifo : fifo_a := (others => (others => '0')); @@ -105,7 +80,7 @@ architecture testbench of wb_ddr_ctrl_wb_sc_tb is begin -- testbench -- component instantiation - DUT: wb_ddr_ctrl_wb_sc + DUT: entity work.wb_ddr_ctrl_wb_sc generic map ( burst_length => burst_length, burst_length_ln2 => burst_length_ln2, @@ -113,14 +88,17 @@ begin -- testbench 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, + wb_mem_rdrq => wb_mem_rdrq, + wb_mem_wrrq => wb_mem_wrrq, + wb_mem_adr => wb_mem_adr, + wb_mem_dat_o => wb_mem_dat_o, + wb_mem_sel => wb_mem_sel, + wb_mem_ack => wb_mem_ack, + wb_mem_dat_i => wb_mem_dat_i, ddr_din => ddr_din, ddr_dout => ddr_dout, ddr_adr => ddr_adr, @@ -149,6 +127,8 @@ begin -- testbench rst_i <= '0'; wait until rising_edge(clk_i); + -- Test VGA read port + vga_mem_rdrq <= '1'; vga_mem_adr <= x"00010"; wait until rising_edge(clk_i); @@ -185,72 +165,68 @@ begin -- testbench 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); + -- Test wb read port - -- 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'; + wb_mem_rdrq <= '1'; + wb_mem_adr <= x"00010"; wait until rising_edge(clk_i); + wb_mem_rdrq <= '0'; + ctr := 0; + while ctr < burst_length loop + if wb_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 wb_mem_dat_i = expected_data report "Incorrect read data (WB)" severity failure; + ctr := ctr + 1; + end if; + + wait until rising_edge(clk_i); + end loop; + + wb_mem_rdrq <= '1'; + wb_mem_adr <= x"10010"; wait until rising_edge(clk_i); - wait until rising_edge(clk_i); + wb_mem_rdrq <= '0'; + + ctr := 0; + while ctr < burst_length loop + if wb_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 wb_mem_dat_i = expected_data report "Incorrect read data (WB)" severity failure; + ctr := ctr + 1; + end if; + + wait until rising_edge(clk_i); + end loop; + + -- Test wb write port + wb_mem_wrrq <= '1'; + wb_mem_adr <= x"10010"; + wb_mem_dat_o <= x"de00ad00be00ef00"; + --wait until rising_edge(clk_i); + + + ctr := 0; + while ctr < burst_length loop + if wb_mem_ack = '1' then + ctr := ctr + 1; + wb_mem_dat_o(7 downto 0) <= std_logic_vector(to_unsigned(ctr, 8)); + end if; + + wait until rising_edge(clk_i); + wb_mem_wrrq <= '0'; + end loop; + sim_done <= true; wait; end process WaveGen_Proc; emul_fifo_to_ddr : process - constant max_fill : integer := 7; + constant max_fill : integer := 2; variable fill : integer := 0; variable ctr : integer := 0; begin @@ -266,7 +242,9 @@ begin -- testbench fill := fill + 1; end if; if ctr >= readrate then - fill := fill - 1; + if fill > 0 then + fill := fill - 1; + end if; ctr := 0; else ctr := ctr + 1; diff --git a/tb/wb_mem_bridge_tb.vhd b/tb/wb_mem_bridge_tb.vhd new file mode 100644 index 0000000..96c6be6 --- /dev/null +++ b/tb/wb_mem_bridge_tb.vhd @@ -0,0 +1,361 @@ +------------------------------------------------------------------------------- +-- 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-06-04 +-- 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_mem_bridge_tb is + +end wb_mem_bridge_tb; + +------------------------------------------------------------------------------- + +architecture testbench of wb_mem_bridge_tb is + + -- 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 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 wb_mem_rdrq : std_logic := '0'; + signal wb_mem_wrrq : std_logic := '0'; + signal wb_mem_adr : std_logic_vector(19 downto 0); + signal wb_mem_dat_o : std_logic_vector(63 downto 0); + signal wb_mem_sel : std_logic_vector(7 downto 0); + signal wb_mem_ack : std_logic; + signal wb_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 wbs_i : mem_bridge_wbs_i_type; + signal wbs_o : mem_bridge_wbs_o_type; + + signal sim_done : boolean := false; + constant maxdelay : integer := 8; + signal delay : integer range 0 to maxdelay := 2; + signal readrate : integer := 1; + + 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: entity work.wb_mem_bridge + 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, + + wb_mem_rdrq => wb_mem_rdrq, + wb_mem_wrrq => wb_mem_wrrq, + wb_mem_adr => wb_mem_adr, + wb_mem_dat_o => wb_mem_dat_o, + wb_mem_sel => wb_mem_sel, + wb_mem_ack => wb_mem_ack, + wb_mem_dat_i => wb_mem_dat_i + ); + + + mem_ctrl_inst: entity work.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, + 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, + wb_mem_rdrq => wb_mem_rdrq, + wb_mem_wrrq => wb_mem_wrrq, + wb_mem_adr => wb_mem_adr, + wb_mem_dat_o => wb_mem_dat_o, + wb_mem_sel => wb_mem_sel, + wb_mem_ack => wb_mem_ack, + wb_mem_dat_i => wb_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'; + wbs_i.stb_i <= '0'; + wbs_i.cyc_i <= '0'; + + wait for 50 ns; + wait until rising_edge(clk_i); + + rst_i <= '0'; + wait until rising_edge(clk_i); + + -- Read miss (on clean buffer) + wbs_i.stb_i <= '1'; + wbs_i.cyc_i <= '1'; + wbs_i.we_i <= '0'; + wbs_i.adr_i <= std_logic_vector(to_unsigned(16#000002#, 24)); + 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"00000001" report "Incorrect read data (WB)" severity error; + wbs_i.stb_i <= '0'; + wbs_i.cyc_i <= '0'; + wait until rising_edge(clk_i); + + -- Write hit + wbs_i.stb_i <= '1'; + wbs_i.cyc_i <= '1'; + wbs_i.we_i <= '1'; + wbs_i.adr_i <= std_logic_vector(to_unsigned(16#000000#, 24)); + 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.stb_i <= '0'; + wbs_i.cyc_i <= '0'; + wait until rising_edge(clk_i); + + -- Read hit + wbs_i.stb_i <= '1'; + wbs_i.cyc_i <= '1'; + wbs_i.we_i <= '0'; + wbs_i.adr_i <= std_logic_vector(to_unsigned(16#000000#, 24)); + 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"DEADBEEF" report "Incorrect read data (WB)" severity error; + wbs_i.stb_i <= '0'; + wbs_i.cyc_i <= '0'; + wait until rising_edge(clk_i); + + -- Read miss (on dirty buffer) + wbs_i.stb_i <= '1'; + wbs_i.cyc_i <= '1'; + wbs_i.we_i <= '0'; + wbs_i.adr_i <= std_logic_vector(to_unsigned(16#000020#, 24)); + 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"00000010" report "Incorrect read data (WB)" severity error; + wbs_i.stb_i <= '0'; + wbs_i.cyc_i <= '0'; + wait until rising_edge(clk_i); + + -- Write miss (on clean buffer) + wbs_i.stb_i <= '1'; + wbs_i.cyc_i <= '1'; + wbs_i.we_i <= '1'; + wbs_i.adr_i <= std_logic_vector(to_unsigned(16#000033#, 24)); + 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.stb_i <= '0'; + wbs_i.cyc_i <= '0'; + wait until rising_edge(clk_i); + + -- Write miss (on dirty buffer) + wbs_i.stb_i <= '1'; + wbs_i.cyc_i <= '1'; + wbs_i.we_i <= '1'; + wbs_i.adr_i <= std_logic_vector(to_unsigned(16#000044#, 24)); + 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.stb_i <= '0'; + wbs_i.cyc_i <= '0'; + wait until rising_edge(clk_i); + + -- Test VGA read port + + 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; + + sim_done <= true; + wait; + end process WaveGen_Proc; + + emul_fifo_to_ddr : process + constant max_fill : integer := 2; + 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 + if fill > 0 then + fill := fill - 1; + end if; + 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 index 8c8352f..4494e97 100644 --- a/wb_ddr_ctrl_wb_sc_tb.wcfg +++ b/wb_ddr_ctrl_wb_sc_tb.wcfg @@ -5,17 +5,15 @@ - - - + sim_done sim_done @@ -52,99 +50,6 @@ 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 @@ -163,6 +68,37 @@ vga_mem_dat_i[63:0] HEXRADIX + + wb_mem_rdrq + wb_mem_rdrq + + + wb_mem_wrrq + wb_mem_wrrq + + + wb_mem_adr[19:0] + wb_mem_adr[19:0] + HEXRADIX + + + wb_mem_dat_o[63:0] + wb_mem_dat_o[63:0] + HEXRADIX + + + wb_mem_sel[7:0] + wb_mem_sel[7:0] + + + wb_mem_ack + wb_mem_ack + + + wb_mem_dat_i[63:0] + wb_mem_dat_i[63:0] + HEXRADIX + ddr_din[63:0] ddr_din[63:0] @@ -202,59 +138,53 @@ fifo_from_ddr_empty fifo_from_ddr_empty - - cfe_mem_adr[19:0] - cfe_mem_adr[19:0] + + p_rdrq[1:0] + p_rdrq[1:0] - - cfe_mem_rdrq - cfe_mem_rdrq + + p_wrrq[1:0] + p_wrrq[1:0] - - cfe_mem_wrrq - cfe_mem_wrrq + + p_ack[1:0] + p_ack[1:0] - - cfe_mem_dat_o[63:0] - cfe_mem_dat_o[63:0] + + p_adr[1:0] + p_adr[1:0] HEXRADIX - - cfe_mem_ack - cfe_mem_ack - - - cfe_mem_dat_i[63:0] - cfe_mem_dat_i[63:0] + + p_dat_o[1:0] + p_dat_o[1:0] HEXRADIX - - vga_rdrq_reg - vga_rdrq_reg + + p_dat_i[1:0] + p_dat_i[1:0] + HEXRADIX - - vga_adr_reg[19:0] - vga_adr_reg[19:0] + + p_sel[1:0] + p_sel[1:0] - - vga_rq_complete - vga_rq_complete + + rdrq_reg[1:0] + rdrq_reg[1:0] - - cfe_rdrq_reg - cfe_rdrq_reg + + wrrq_reg[1:0] + wrrq_reg[1:0] - - cfe_wrrq_reg - cfe_wrrq_reg + + adr_reg[1:0] + adr_reg[1:0] + HEXRADIX - - cfe_adr_reg[19:0] - cfe_adr_reg[19:0] - - - cfe_rq_complete - cfe_rq_complete + + rq_complete[1:0] + rq_complete[1:0] dout_data_valid @@ -292,320 +222,8 @@ 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 - + + fifo_to_ddr_full_last + fifo_to_ddr_full_last diff --git a/wb_mem_bridge_tb.wcfg b/wb_mem_bridge_tb.wcfg new file mode 100644 index 0000000..e58cafb --- /dev/null +++ b/wb_mem_bridge_tb.wcfg @@ -0,0 +1,336 @@ + + + + + + + + + + + + + + + + + + + + + + + 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 + + + .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 + + + + wb_mem_rdrq + wb_mem_rdrq + + + wb_mem_wrrq + wb_mem_wrrq + + + wb_mem_adr[19:0] + wb_mem_adr[19:0] + HEXRADIX + + + wb_mem_dat_o[63:0] + wb_mem_dat_o[63:0] + HEXRADIX + + + wb_mem_sel[7:0] + wb_mem_sel[7:0] + + + wb_mem_ack + wb_mem_ack + + + wb_mem_dat_i[63:0] + wb_mem_dat_i[63:0] + HEXRADIX + + + buf_dirty[63:0] + buf_dirty[63:0] + + + buf_valid + buf_valid + + + buf_tag[25:6] + buf_tag[25:6] + HEXRADIX + + + buf_adr[2:0] + buf_adr[2:0] + UNSIGNEDDECRADIX + + + buf_bwe[7:0] + buf_bwe[7:0] + + + buf_hit + buf_hit + + + buf_dat_o[63:0] + buf_dat_o[63:0] + HEXRADIX + + + buf_dat_i[63:0] + buf_dat_i[63:0] + HEXRADIX + + + wb_in_cyc + wb_in_cyc + + + write_flush + write_flush + + + read_fill + read_fill + + + buf_wbwr + buf_wbwr + + + ctr[2:0] + ctr[2:0] + + + mem_ctrl + label + + clk_i + clk_i + + + rst_i + rst_i + + + vga_mem_rdrq + vga_mem_rdrq + + + vga_mem_adr[19:0] + vga_mem_adr[19:0] + + + vga_mem_ack + vga_mem_ack + + + vga_mem_dat_i[63:0] + vga_mem_dat_i[63:0] + + + wb_mem_rdrq + wb_mem_rdrq + + + wb_mem_wrrq + wb_mem_wrrq + + + wb_mem_adr[19:0] + wb_mem_adr[19:0] + + + wb_mem_dat_o[63:0] + wb_mem_dat_o[63:0] + + + wb_mem_sel[7:0] + wb_mem_sel[7:0] + + + wb_mem_ack + wb_mem_ack + + + wb_mem_dat_i[63:0] + wb_mem_dat_i[63:0] + + + ddr_din[63:0] + ddr_din[63:0] + + + ddr_dout[63:0] + ddr_dout[63:0] + + + ddr_adr[22:0] + ddr_adr[22:0] + + + 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 + + + p_rdrq[1:0] + p_rdrq[1:0] + + + p_wrrq[1:0] + p_wrrq[1:0] + + + p_ack[1:0] + p_ack[1:0] + + + p_adr[1:0] + p_adr[1:0] + + + p_dat_o[1:0] + p_dat_o[1:0] + + + p_dat_i[1:0] + p_dat_i[1:0] + + + p_sel[1:0] + p_sel[1:0] + + + rdrq_reg[1:0] + rdrq_reg[1:0] + + + wrrq_reg[1:0] + wrrq_reg[1:0] + + + adr_reg[1:0] + adr_reg[1:0] + + + rq_complete[1:0] + rq_complete[1:0] + + + 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 + + + fifo_to_ddr_full_last + fifo_to_ddr_full_last + + +