- Some optimization

- Cache manual flush/invalidate is now whole cache instead of by address
This commit is contained in:
2013-03-19 20:24:28 +01:00
parent 973513900d
commit 37d63b062d
10 changed files with 348 additions and 5369 deletions

View File

@@ -65,6 +65,7 @@ XSTOPTS="-ifn $(PRJFILE) \
-iob auto \ -iob auto \
-keep_hierarchy soft \ -keep_hierarchy soft \
-register_balancing yes \ -register_balancing yes \
-auto_bram_packing yes \
$(addprefix -uc ,$(XCF))" $(addprefix -uc ,$(XCF))"
NGDOPTS=-p $(PART) -aul -aut $(addprefix -uc ,$(UCF)) -sd coregen/ NGDOPTS=-p $(PART) -aul -aut $(addprefix -uc ,$(UCF)) -sd coregen/
MAPOPTS=-p $(PART) -cm balanced -timing -ol high -logic_opt on -xe n -detail MAPOPTS=-p $(PART) -cm balanced -timing -ol high -logic_opt on -xe n -detail

View File

@@ -93,12 +93,13 @@ pixelreader : process(clk)
mem_rdrq <= '1'; mem_rdrq <= '1';
mem_adr <= std_logic_vector(to_unsigned(framebuffer0_base/(burst_length*8)+addr_ctr, mem_adr'length)); mem_adr <= std_logic_vector(to_unsigned(framebuffer0_base/(burst_length*8)+addr_ctr, mem_adr'length));
burst_ctr <= 0; --burst_ctr <= 0;
state <= S_READ; state <= S_READ;
end if; end if;
when S_READ => when S_READ =>
if mem_ack = '1' then if mem_ack = '1' then
if burst_ctr = burst_length-1 then if burst_ctr = burst_length-1 then
burst_ctr <= 0;
if addr_ctr = (pixels/(4*burst_length))-1 then if addr_ctr = (pixels/(4*burst_length))-1 then
addr_ctr <= 0; addr_ctr <= 0;
state <= S_WAIT_VSYNC; state <= S_WAIT_VSYNC;

View File

@@ -134,6 +134,9 @@ component wb_ddr_ctrl_wb_sc is
); );
end component; end component;
component wb_ddr_ctrl_wb_dc is component wb_ddr_ctrl_wb_dc is
generic (
dontcare : std_logic
);
Port ( Port (
-- Control signals -- Control signals
ddr2_clk0 : in std_ulogic; ddr2_clk0 : in std_ulogic;
@@ -244,38 +247,41 @@ d2s_fifo : wb_ddr_ctrl_wb_from_ddr
); );
ddr_cd_inst : wb_ddr_ctrl_wb_dc ddr_cd_inst : wb_ddr_ctrl_wb_dc
port map ( generic map (
-- Control signals dontcare => dontcare
ddr2_clk0 => ddr2_clk0, )
ddr2_clk180 => ddr2_clk180, port map (
ddr2_clk90 => ddr2_clk90, -- Control signals
ddr2_reset => ddr2_reset, ddr2_clk0 => ddr2_clk0,
ddr2_clk180 => ddr2_clk180,
-- to DDR2 controller ddr2_clk90 => ddr2_clk90,
ctrl_input_data => ctrl_input_data, ddr2_reset => ddr2_reset,
ctrl_data_mask => ctrl_data_mask,
ctrl_output_data => ctrl_output_data, -- to DDR2 controller
ctrl_data_valid => ctrl_data_valid, ctrl_input_data => ctrl_input_data,
ctrl_input_address => ctrl_input_address, ctrl_data_mask => ctrl_data_mask,
ctrl_command_register => ctrl_command_register, ctrl_output_data => ctrl_output_data,
ctrl_burst_done => ctrl_burst_done, ctrl_data_valid => ctrl_data_valid,
ctrl_auto_ref_req => ctrl_auto_ref_req, ctrl_input_address => ctrl_input_address,
ctrl_cmd_ack => ctrl_cmd_ack, ctrl_command_register => ctrl_command_register,
ctrl_init_done => ctrl_init_done, ctrl_burst_done => ctrl_burst_done,
ctrl_ar_done => ctrl_ar_done, ctrl_auto_ref_req => ctrl_auto_ref_req,
ctrl_cmd_ack => ctrl_cmd_ack,
-- To/from system clock domain ctrl_init_done => ctrl_init_done,
din => std_ulogic_vector(s2d_fifo_dout(63 downto 0)), ctrl_ar_done => ctrl_ar_done,
dout => d2s_fifo_din,
adr => std_ulogic_vector(s2d_fifo_dout(86 downto 64)), -- To/from system clock domain
we => s2d_fifo_dout(87), din => std_ulogic_vector(s2d_fifo_dout(63 downto 0)),
be => std_ulogic_vector(s2d_fifo_dout(95 downto 88)), dout => d2s_fifo_din,
adr => std_ulogic_vector(s2d_fifo_dout(86 downto 64)),
fifo_to_sys_write => d2s_fifo_wr, we => s2d_fifo_dout(87),
fifo_from_sys_read => s2d_fifo_rd, be => std_ulogic_vector(s2d_fifo_dout(95 downto 88)),
fifo_to_sys_full => d2s_fifo_full,
fifo_from_sys_empty => s2d_fifo_empty, fifo_to_sys_write => d2s_fifo_wr,
fifo_from_sys_almost_empty => s2d_fifo_almost_empty fifo_from_sys_read => s2d_fifo_rd,
fifo_to_sys_full => d2s_fifo_full,
fifo_from_sys_empty => s2d_fifo_empty,
fifo_from_sys_almost_empty => s2d_fifo_almost_empty
); );
end Behavioral; end Behavioral;

View File

@@ -32,44 +32,50 @@ use IEEE.STD_LOGIC_1164.ALL;
--use UNISIM.VComponents.all; --use UNISIM.VComponents.all;
entity wb_ddr_ctrl_wb_dc is entity wb_ddr_ctrl_wb_dc is
Port ( generic (
-- Control signals dontcare : std_logic := '-'
ddr2_clk0 : in std_ulogic; );
ddr2_clk180 : in std_ulogic; Port (
ddr2_clk90 : in std_ulogic; -- Control signals
ddr2_reset : in std_ulogic; ddr2_clk0 : in std_ulogic;
ddr2_clk180 : in std_ulogic;
-- to DDR2 controller ddr2_clk90 : in std_ulogic;
ctrl_input_data : out std_logic_vector(31 downto 0); ddr2_reset : in std_ulogic;
ctrl_data_mask : out std_logic_vector(3 downto 0);
ctrl_output_data : in std_logic_vector(31 downto 0) := (others => 'Z'); -- to DDR2 controller
ctrl_data_valid : in std_logic; ctrl_input_data : out std_logic_vector(31 downto 0);
ctrl_input_address : out std_logic_vector(((13 + 10 + 2)-1) downto 0); ctrl_data_mask : out std_logic_vector(3 downto 0);
ctrl_command_register : out std_logic_vector(2 downto 0); ctrl_output_data : in std_logic_vector(31 downto 0) := (others => 'Z');
ctrl_burst_done : out std_logic; ctrl_data_valid : in std_logic;
ctrl_auto_ref_req : in std_logic; ctrl_input_address : out std_logic_vector(((13 + 10 + 2)-1) downto 0);
ctrl_cmd_ack : in std_logic; ctrl_command_register : out std_logic_vector(2 downto 0);
ctrl_init_done : in std_logic; ctrl_burst_done : out std_logic;
ctrl_ar_done : in std_logic; ctrl_auto_ref_req : in std_logic;
ctrl_cmd_ack : in std_logic;
-- To/from system clock domain ctrl_init_done : in std_logic;
din : in std_ulogic_vector(63 downto 0); ctrl_ar_done : in std_logic;
dout : out std_ulogic_vector(63 downto 0);
adr : in std_ulogic_vector(22 downto 0); -- To/from system clock domain
we : in std_ulogic; din : in std_ulogic_vector(63 downto 0);
be : in std_ulogic_vector(7 downto 0); dout : out std_ulogic_vector(63 downto 0);
adr : in std_ulogic_vector(22 downto 0);
fifo_to_sys_write : out std_ulogic; we : in std_ulogic;
fifo_from_sys_read : out std_ulogic; be : in std_ulogic_vector(7 downto 0);
fifo_to_sys_full : in std_ulogic;
fifo_from_sys_empty : in std_ulogic; fifo_to_sys_write : out std_ulogic;
fifo_from_sys_almost_empty : in std_logic 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 wb_ddr_ctrl_wb_dc; end wb_ddr_ctrl_wb_dc;
architecture Behavioral of wb_ddr_ctrl_wb_dc is architecture Behavioral of wb_ddr_ctrl_wb_dc is
component wb_ddr_ctrl_wb_dc_fsm component wb_ddr_ctrl_wb_dc_fsm
generic (
dontcare : std_logic
);
port ( port (
ddr2_clk0 : in std_ulogic; ddr2_clk0 : in std_ulogic;
ddr2_clk90 : in std_ulogic; ddr2_clk90 : in std_ulogic;
@@ -83,7 +89,7 @@ architecture Behavioral of wb_ddr_ctrl_wb_dc is
fifo_from_sys_empty : in std_ulogic; fifo_from_sys_empty : in std_ulogic;
fifo_from_sys_almost_empty : in std_logic; fifo_from_sys_almost_empty : in std_logic;
we : in std_ulogic; we : in std_ulogic;
row_addr : in std_ulogic_vector(12 downto 0);
ddr_address_en : out std_ulogic; ddr_address_en : out std_ulogic;
ddr_dout_en : out std_ulogic; ddr_dout_en : out std_ulogic;
ddr_dout_high : out std_ulogic; ddr_dout_high : out std_ulogic;
@@ -114,6 +120,9 @@ signal ctrl_data_valid_toggle : std_ulogic := '0';
begin begin
wb_ddr_ctrl_wb_dc_fsm_inst: wb_ddr_ctrl_wb_dc_fsm wb_ddr_ctrl_wb_dc_fsm_inst: wb_ddr_ctrl_wb_dc_fsm
generic map (
dontcare => dontcare
)
port map ( port map (
ddr2_clk0 => ddr2_clk0, ddr2_clk0 => ddr2_clk0,
ddr2_clk90 => ddr2_clk90, ddr2_clk90 => ddr2_clk90,
@@ -127,7 +136,6 @@ wb_ddr_ctrl_wb_dc_fsm_inst: wb_ddr_ctrl_wb_dc_fsm
fifo_from_sys_empty => fifo_from_sys_empty, fifo_from_sys_empty => fifo_from_sys_empty,
fifo_from_sys_almost_empty => fifo_from_sys_almost_empty, fifo_from_sys_almost_empty => fifo_from_sys_almost_empty,
we => we, we => we,
row_addr => adr(20 downto 8),
ddr_address_en => ddr_address_en, ddr_address_en => ddr_address_en,
ddr_dout_en => ddr_dout_en, ddr_dout_en => ddr_dout_en,
ddr_dout_high => ddr_dout_high, ddr_dout_high => ddr_dout_high,
@@ -138,7 +146,7 @@ wb_ddr_ctrl_wb_dc_fsm_inst: wb_ddr_ctrl_wb_dc_fsm
ctrl_burst_done_d => ctrl_burst_done_d, ctrl_burst_done_d => ctrl_burst_done_d,
fifo_from_sys_read => fifo_from_sys_read fifo_from_sys_read => fifo_from_sys_read
); );
-- ddr_address register -- ddr_address register
ddr_address_reg : process(ddr2_clk180) ddr_address_reg : process(ddr2_clk180)
begin begin
@@ -149,7 +157,7 @@ ddr_address_reg : process(ddr2_clk180)
end if; end if;
end process ddr_address_reg; end process ddr_address_reg;
-- remap address for ddr controller (so column is lowest) -- remap address for ddr controller (bank:row:column)
ctrl_input_address <= std_logic_vector(ddr_address(20 downto 8) & ddr_address(7 downto 0) & "00" & ddr_address(22 downto 21)); ctrl_input_address <= std_logic_vector(ddr_address(20 downto 8) & ddr_address(7 downto 0) & "00" & ddr_address(22 downto 21));
-- ddr_dout register -- ddr_dout register

View File

@@ -32,6 +32,9 @@ use IEEE.STD_LOGIC_1164.ALL;
--use UNISIM.VComponents.all; --use UNISIM.VComponents.all;
entity wb_ddr_ctrl_wb_dc_fsm is entity wb_ddr_ctrl_wb_dc_fsm is
generic (
dontcare : std_logic := '-'
);
port ( port (
-- Control signals -- Control signals
ddr2_clk0 : in std_ulogic; ddr2_clk0 : in std_ulogic;
@@ -48,7 +51,6 @@ entity wb_ddr_ctrl_wb_dc_fsm is
fifo_from_sys_empty : in std_ulogic; fifo_from_sys_empty : in std_ulogic;
fifo_from_sys_almost_empty : in std_logic; fifo_from_sys_almost_empty : in std_logic;
we : in std_ulogic; we : in std_ulogic;
row_addr : in std_ulogic_vector(12 downto 0);
-- Outputs -- Outputs
ddr_address_en : out std_ulogic; ddr_address_en : out std_ulogic;
@@ -75,7 +77,6 @@ type ctrl_states is (S_RESET, S_INITIALIZE, S_WAITINITDONE, S_IDLE, S_REFRESH, S
S_WRITE2, S_WRITE3, S_WRITE_END1, S_WRITE_END2, S_WRITE_END3, S_READ1, S_READ2, S_WRITE2, S_WRITE3, S_WRITE_END1, S_WRITE_END2, S_WRITE_END3, S_READ1, S_READ2,
S_READ3, S_READ4, S_READ5, S_READ_END1, S_READ_END2); S_READ3, S_READ4, S_READ5, S_READ_END1, S_READ_END2);
signal ctrl_state : ctrl_states := S_RESET; signal ctrl_state : ctrl_states := S_RESET;
signal burst_start_adr : std_ulogic_vector(12 downto 0) := (others => '-');
signal fifo_pending : std_ulogic := '0'; signal fifo_pending : std_ulogic := '0';
-- fifo_pending is '1' when a valid, unprocessed request is on the fifo outputs -- fifo_pending is '1' when a valid, unprocessed request is on the fifo outputs
@@ -84,20 +85,18 @@ signal fifo_from_sys_read_int, fifo_from_sys_valid : std_ulogic := '0';
begin begin
is_fifo_from_sys_valid : process(ddr2_clk180)
begin
if rising_edge(ddr2_clk180) then
if fifo_from_sys_read_int = '1' then
fifo_from_sys_valid <= not fifo_from_sys_empty;
end if;
end if;
end process is_fifo_from_sys_valid;
fifo_from_sys_read <= fifo_from_sys_read_int and not fifo_from_sys_empty;
is_fifo_from_sys_valid : process(ddr2_clk180)
begin ctrl_fsm_state : process(ddr2_clk180)
if rising_edge(ddr2_clk180) then
if fifo_from_sys_read_int = '1' then
fifo_from_sys_valid <= not fifo_from_sys_empty;
end if;
end if;
end process is_fifo_from_sys_valid;
fifo_from_sys_read <= fifo_from_sys_read_int and not fifo_from_sys_empty;
ctrl_fsm_state : process(ddr2_clk180)
begin begin
if rising_edge(ddr2_clk180) then if rising_edge(ddr2_clk180) then
if ddr2_reset = '1' then if ddr2_reset = '1' then
@@ -125,22 +124,22 @@ ctrl_fsm_state : process(ddr2_clk180)
ctrl_state <= S_IDLE; ctrl_state <= S_IDLE;
end if; end if;
when S_REQUEST_INIT => when S_REQUEST_INIT =>
fifo_pending <= '-'; fifo_pending <= dontcare;
if we = '1' then if we = '1' then
ctrl_state <= S_WRITE1; ctrl_state <= S_WRITE1;
else else
ctrl_state <= S_READ1; ctrl_state <= S_READ1;
end if; end if;
burst_start_adr <= row_addr; --burst_start_adr <= row_addr;
when S_WRITE1 => when S_WRITE1 =>
fifo_pending <= '-'; fifo_pending <= dontcare;
if ctrl_cmd_ack = '1' then if ctrl_cmd_ack = '1' then
ctrl_state <= S_WRITE2; ctrl_state <= S_WRITE2;
end if; end if;
when S_WRITE2 => when S_WRITE2 =>
fifo_pending <= '-'; fifo_pending <= dontcare;
if fifo_from_sys_valid = '0' or row_addr /= burst_start_adr or if fifo_from_sys_valid = '0' or --row_addr /= burst_start_adr or
we = '0' then -- or ctrl_auto_ref_req = '1' then we = '0' then -- or ctrl_auto_ref_req = '1' then
-- next request incompatible with burst type, or auto refresh requested -- next request incompatible with burst type, or auto refresh requested
fifo_pending <= fifo_from_sys_valid; fifo_pending <= fifo_from_sys_valid;
@@ -149,7 +148,7 @@ ctrl_fsm_state : process(ddr2_clk180)
ctrl_state <= S_WRITE3; ctrl_state <= S_WRITE3;
end if; end if;
when S_WRITE3 => when S_WRITE3 =>
fifo_pending <= '-'; fifo_pending <= dontcare;
ctrl_state <= S_WRITE2; ctrl_state <= S_WRITE2;
when S_WRITE_END1 => when S_WRITE_END1 =>
@@ -162,19 +161,19 @@ ctrl_fsm_state : process(ddr2_clk180)
end if; end if;
when S_READ1 => when S_READ1 =>
fifo_pending <= '-'; fifo_pending <= dontcare;
if ctrl_cmd_ack = '1' then if ctrl_cmd_ack = '1' then
ctrl_state <= S_READ2; ctrl_state <= S_READ2;
end if; end if;
when S_READ2 => when S_READ2 =>
fifo_pending <= '-'; fifo_pending <= dontcare;
ctrl_state <= S_READ3; ctrl_state <= S_READ3;
when S_READ3 => when S_READ3 =>
fifo_pending <= '-'; fifo_pending <= dontcare;
ctrl_state <= S_READ4; ctrl_state <= S_READ4;
when S_READ4 => when S_READ4 =>
fifo_pending <= '-'; fifo_pending <= dontcare;
if fifo_from_sys_valid = '0' or row_addr /= burst_start_adr or if fifo_from_sys_valid = '0' or --row_addr /= burst_start_adr or
we = '1' then -- or ctrl_auto_ref_req = '1' then we = '1' then -- or ctrl_auto_ref_req = '1' then
-- next request incompatible with burst type, or auto refresh requested -- next request incompatible with burst type, or auto refresh requested
fifo_pending <= fifo_from_sys_valid; fifo_pending <= fifo_from_sys_valid;
@@ -183,7 +182,7 @@ ctrl_fsm_state : process(ddr2_clk180)
ctrl_state <= S_READ5; ctrl_state <= S_READ5;
end if; end if;
when S_READ5 => when S_READ5 =>
fifo_pending <= '-'; fifo_pending <= dontcare;
ctrl_state <= S_READ4; ctrl_state <= S_READ4;
when S_READ_END1 => when S_READ_END1 =>
@@ -196,29 +195,17 @@ ctrl_fsm_state : process(ddr2_clk180)
end if; end if;
end if; end if;
end process ctrl_fsm_state; end process ctrl_fsm_state;
-- input FIFO control
--fifo_from_sys_read_int <= '1' when ((ctrl_state = S_IDLE and ctrl_auto_ref_req = '0' and fifo_pending = '0') or
-- (ctrl_state = S_REQUEST_INIT and we = '1') or
-- (ctrl_state = S_WRITE1 and ctrl_cmd_ack = '1') or
-- (ctrl_state = S_WRITE2 and not (fifo_from_sys_valid = '0' or row_addr /= burst_start_adr or
-- we = '0' or ctrl_auto_ref_req = '1')) or
-- (ctrl_state = S_WRITE4) or
-- (ctrl_state = S_READ3 or ctrl_state = S_READ5) or
-- (ctrl_state = S_READ4 and not (fifo_from_sys_valid = '0' or row_addr /= burst_start_adr or
-- we = '1' or ctrl_auto_ref_req = '1')) or
-- (ctrl_state = S_READ2)
-- ) else
-- '0';
ctrl_fsm_out : process(ctrl_state, ddr2_reset, we, ctrl_cmd_ack, fifo_from_sys_valid, ctrl_fsm_out : process(ctrl_state, ddr2_reset, we, ctrl_cmd_ack, fifo_from_sys_valid,
row_addr, burst_start_adr, ctrl_auto_ref_req, fifo_pending, --row_addr, burst_start_adr,
fifo_from_sys_almost_empty) ctrl_auto_ref_req, fifo_pending,
fifo_from_sys_almost_empty)
begin begin
ddr_dmask_rst <= '0'; -- dmask register reset ddr_dmask_rst <= '0'; -- dmask register reset
ddr_dmask_en <= '0'; -- dmask register enable ddr_dmask_en <= '0'; -- dmask register enable
ddr_dout_en <= '0'; -- output register enable ddr_dout_en <= '0'; -- output register enable
ddr_dout_high <= '-'; -- output register low/high mux ddr_dout_high <= dontcare; -- output register low/high mux
ddr_address_en <= '0'; -- address register enable ddr_address_en <= '0'; -- address register enable
dout_low_en <= '0'; -- input data lower half register enable dout_low_en <= '0'; -- input data lower half register enable
ctrl_burst_done_d <= '0'; ctrl_burst_done_d <= '0';
@@ -257,7 +244,7 @@ ctrl_fsm_out : process(ctrl_state, ddr2_reset, we, ctrl_cmd_ack, fifo_from_sys_v
ddr_dmask_en <= '1'; ddr_dmask_en <= '1';
ddr_dout_en <= '1'; ddr_dout_en <= '1';
ddr_dout_high <= '0'; ddr_dout_high <= '0';
if fifo_from_sys_valid = '0' or row_addr /= burst_start_adr or if fifo_from_sys_valid = '0' or --row_addr /= burst_start_adr or
we = '0' then -- or ctrl_auto_ref_req = '1' then we = '0' then -- or ctrl_auto_ref_req = '1' then
-- next request incompatible with burst type, or auto refresh requested -- next request incompatible with burst type, or auto refresh requested
@@ -277,6 +264,7 @@ ctrl_fsm_out : process(ctrl_state, ddr2_reset, we, ctrl_cmd_ack, fifo_from_sys_v
fifo_from_sys_read_int <= '1'; fifo_from_sys_read_int <= '1';
when S_WRITE_END1 => when S_WRITE_END1 =>
ctrl_burst_done_d <= '1'; ctrl_burst_done_d <= '1';
ctrl_command_register_d <= ctrl_command_write;
when S_WRITE_END2 => when S_WRITE_END2 =>
ctrl_burst_done_d <= '1'; ctrl_burst_done_d <= '1';
@@ -289,8 +277,9 @@ ctrl_fsm_out : process(ctrl_state, ddr2_reset, we, ctrl_cmd_ack, fifo_from_sys_v
ctrl_command_register_d <= ctrl_command_read; ctrl_command_register_d <= ctrl_command_read;
fifo_from_sys_read_int <= '1'; fifo_from_sys_read_int <= '1';
when S_READ4 => when S_READ4 =>
ctrl_command_register_d <= ctrl_command_read;
ddr_address_en <= '1'; ddr_address_en <= '1';
if fifo_from_sys_valid = '0' or row_addr /= burst_start_adr or if fifo_from_sys_valid = '0' or --row_addr /= burst_start_adr or
we = '1' then -- or ctrl_auto_ref_req = '1' then we = '1' then -- or ctrl_auto_ref_req = '1' then
-- next request incompatible with burst type, or auto refresh requested -- next request incompatible with burst type, or auto refresh requested
ctrl_burst_done_d <= '1'; ctrl_burst_done_d <= '1';
@@ -302,6 +291,7 @@ ctrl_fsm_out : process(ctrl_state, ddr2_reset, we, ctrl_cmd_ack, fifo_from_sys_v
ctrl_command_register_d <= ctrl_command_read; ctrl_command_register_d <= ctrl_command_read;
fifo_from_sys_read_int <= '1'; fifo_from_sys_read_int <= '1';
when S_READ_END1 => when S_READ_END1 =>
ctrl_command_register_d <= ctrl_command_read;
ctrl_burst_done_d <= '1'; ctrl_burst_done_d <= '1';
when others => when others =>

View File

@@ -160,6 +160,7 @@ begin
vga_mem_dat_i <= ddr_dout; vga_mem_dat_i <= ddr_dout;
vga_mem_ack <= dout_data_valid when bus_owner_reg = B_VGA else vga_mem_ack <= dout_data_valid when bus_owner_reg = B_VGA else
'0'; '0';
cfe_mem_dat_i <= ddr_dout; cfe_mem_dat_i <= ddr_dout;
cfe_mem_ack <= dout_data_valid when bus_owner_reg = B_CFE and cfe_rdrq_reg = '1' else 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 not fifo_to_ddr_full when bus_owner_reg = B_CFE and cfe_wrrq_reg = '1' else
@@ -170,8 +171,8 @@ begin
ddr_be <= (others => '0'); ddr_be <= (others => '0');
ddr_din <= cfe_mem_dat_o; ddr_din <= cfe_mem_dat_o;
ddr_adr_int(22 downto 3) <= vga_adr_reg when bus_owner = B_VGA else ddr_adr_int(22 downto 3) <= vga_adr_reg when bus_owner = B_VGA else
cfe_adr_reg when bus_owner = B_CFE else cfe_adr_reg when bus_owner = B_CFE;-- else
(others => dontcare); --(others => dontcare);
ddr_adr_int(2 downto 0) <= std_logic_vector(to_unsigned(out_ctr, 3)); 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 ddr_we_int <= '1' when bus_owner = B_CFE and cfe_wrrq_reg = '1' else
'0'; '0';
@@ -183,11 +184,11 @@ begin
'0'; '0';
ddr_adr <= ddr_adr_int when in_read = '1' else ddr_adr <= ddr_adr_int when in_read = '1' else
ddr_adr_dly(write_delay-1) when in_write = '1' else ddr_adr_dly(write_delay-1) when in_write = '1';-- else
(others => dontcare); --(others => dontcare);
ddr_we <= ddr_we_int when in_read = '1' else ddr_we <= ddr_we_int when in_read = '1' else
ddr_we_dly(write_delay-1) when in_write = '1' else ddr_we_dly(write_delay-1) when in_write = '1';-- else
dontcare; --dontcare;
fifo_to_ddr_write <= fifo_to_ddr_write_int when in_read = '1' else 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 fifo_to_ddr_write_dly(write_delay-1) and not fifo_to_ddr_full when in_write = '1' else
'0'; '0';

View File

@@ -35,13 +35,16 @@ use UNISIM.VComponents.all;
use work.intercon_package.all; use work.intercon_package.all;
-- control slave port register map -- control slave port register map
-- 0: 31..0 - flush_adr -- 0: 0 - invalidate
-- Writing an address to this register causes the cache line containing -- write '1' to invalidate entire cache
-- the memory address' data to be flushed to main memory, if present and dirty. -- 1 - flush
-- 1: 31..0 - invalidate_adr -- write '1' to flush all dirty lines
-- Writing an address to this register causes the cache line containing -- 31..2 - reserved
-- the memory address' data to be invalidated if present. If it was dirty, -- 1: reserved
-- it is flushed first. --
-- 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 entity wb_ddr_ctrl_wb_sc_fe is
generic ( generic (
@@ -95,13 +98,18 @@ architecture Behavioral of wb_ddr_ctrl_wb_sc_fe is
adr_tag_eq : in std_logic_vector(assoc-1 downto 0); adr_tag_eq : in std_logic_vector(assoc-1 downto 0);
eject_dirty : in std_logic; eject_dirty : in std_logic;
mem_offset : in unsigned(line_size_ln2-1 downto 0); 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_flush : in std_logic;
user_cc_req_inval : in std_logic; user_cc_req_inval : in std_logic;
user_cc_read : in std_logic; user_cc_req_none : in std_logic;
adr_tag_eq_num_dirty : in std_logic; adr_tag_eq_num_dirty : in std_logic;
mem_ack : 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; ack_o : out std_logic;
update_lru : out std_logic := '0'; update_lru : out std_logic := '0';
set_clean : out std_logic := '0';
set_dirty : out std_logic := '0'; set_dirty : out std_logic := '0';
set_valid : out std_logic := '0'; set_valid : out std_logic := '0';
set_invalid : out std_logic := '0'; set_invalid : out std_logic := '0';
@@ -110,8 +118,8 @@ architecture Behavioral of wb_ddr_ctrl_wb_sc_fe is
cache_to_mem : out std_logic := '0'; cache_to_mem : out std_logic := '0';
mem_rdrq : out std_logic := '0'; mem_rdrq : out std_logic := '0';
mem_wrrq : out std_logic := '0'; mem_wrrq : out std_logic := '0';
user_cc_ack_o : out std_logic := '0'; mfi : out std_logic := '0';
user_cc : out std_logic := '0'); user_cc_ack_o : out std_logic := '0');
end component; end component;
component wb_ddr_ctrl_wb_sc_fe_ram component wb_ddr_ctrl_wb_sc_fe_ram
@@ -150,9 +158,9 @@ architecture Behavioral of wb_ddr_ctrl_wb_sc_fe is
signal cc_valid : cc_valid_a := (others => (others => '0')); signal cc_valid : cc_valid_a := (others => (others => '0'));
signal cc_dirty : cc_dirty_a := (others => (others => dontcare)); signal cc_dirty : cc_dirty_a := (others => (others => dontcare));
attribute ram_style of cc_tag : signal is "block"; attribute ram_style of cc_tag : signal is "block";
attribute ram_style of cc_lru : signal is "auto"; attribute ram_style of cc_lru : signal is "distributed";
attribute ram_style of cc_valid : signal is "auto"; attribute ram_style of cc_valid : signal is "distributed";
attribute ram_style of cc_dirty : signal is "auto"; attribute ram_style of cc_dirty : signal is "distributed";
signal cc_we : std_logic := '0'; 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_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_tag_wr_data, cc_tag_rd_data : tag_t := (others => dontcare);
@@ -162,7 +170,7 @@ architecture Behavioral of wb_ddr_ctrl_wb_sc_fe is
-- Convenience variable for cc_tag_rd_data -- 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); type tag_a is array(assoc-1 downto 0) of std_logic_vector(tag_width-1 downto 0);
signal tags : tag_a := (others => (others => '-')); signal tags : tag_a := (others => (others => dontcare));
-- Cache data signals / memory -- Cache data signals / memory
-- signal cache_we : std_logic := '0'; -- signal cache_we : std_logic := '0';
@@ -189,10 +197,17 @@ architecture Behavioral of wb_ddr_ctrl_wb_sc_fe is
-- control signals -- control signals
signal update_lru, set_dirty, set_valid, cache_write, cache_from_mem, eject_dirty : std_logic; signal update_lru, set_dirty, set_valid, cache_write, cache_from_mem, eject_dirty : std_logic;
signal set_invalid, cache_to_mem, user_cc, adr_tag_eq_num_dirty : std_logic; signal 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_offset, mem_offset_dly : unsigned(offset_width-1 downto 0);
signal mem_rdrq_int, mem_wrrq_int : std_logic; signal mem_rdrq_int, mem_wrrq_int : std_logic;
signal user_cc_req_flush, user_cc_req_inval, user_cc_read : 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 begin
cache_rd_addr <= adr_index & adr_tag_eq_num & adr_offset when cache_to_mem = '0' else cache_rd_addr <= adr_index & adr_tag_eq_num & adr_offset when cache_to_mem = '0' else
@@ -227,8 +242,8 @@ begin
mem_dat_o <= cache_rd_data; mem_dat_o <= cache_rd_data;
mem_adr <= adr_tag & std_logic_vector(adr_index) when cache_from_mem = '1' else 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' else tags(to_integer(eject_num)) & std_logic_vector(adr_index);-- when cache_to_mem = '1' else
(others => dontcare); --(others => dontcare);
cc_wr_data_gen : for i in 0 to assoc-1 generate 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) <= cc_tag_wr_data((i+1)*tag_width-1 downto i*tag_width) <=
@@ -243,18 +258,20 @@ begin
cc_valid_wr_data(i) <= cc_valid_wr_data(i) <=
'1' when eject_num = i and set_valid = '1' else '1' when eject_num = i and set_valid = '1' else
'0' when adr_tag_eq(i) = '1' and set_invalid = '1' else '0' when (adr_tag_eq(i) = '1' or mfi = '1') and set_invalid = '1' else
cc_valid_rd_data(i); cc_valid_rd_data(i);
cc_dirty_wr_data(i) <= cc_dirty_wr_data(i) <=
'1' when adr_tag_eq(i) = '1' and set_dirty = '1' else '1' when adr_tag_eq(i) = '1' and set_dirty = '1' else
'0' when eject_num = i and set_valid = '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); cc_dirty_rd_data(i);
end generate; end generate;
cc_wr_addr <= adr_index when update_lru = '1' or set_dirty = '1' or set_valid = '1' or set_invalid = '1' else cc_wr_addr <= mfi_index when mfi = '1' else
(others => dontcare); adr_index;-- when update_lru = '1' or set_dirty = '1' or set_valid = '1' or set_invalid = '1' else
cc_we <= update_lru or set_dirty or set_valid or set_invalid; --(others => dontcare);
cc_we <= update_lru or set_dirty or set_valid or set_invalid or set_clean;
-- Memory for cache control -- Memory for cache control
cc_mem : process(clk_i) cc_mem : process(clk_i)
@@ -278,18 +295,19 @@ begin
end process cc_mem; 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; assert addr_width = (wbs_i.adr_i'high - wbs_i.adr_i'low) report "Invalid address width, check parameters" severity error;
adr_index <= unsigned(wbs_cc_i.dat_i(offset_width+index_width+2 downto offset_width+3)) when user_cc = '1' else adr_index <= --unsigned(wbs_cc_i.dat_i(offset_width+index_width+2 downto offset_width+3)) when user_cc = '1' else
unsigned(wbs_i.adr_i(offset_width+index_width+2 downto offset_width+3)) ; 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 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)); 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 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); wbs_i.adr_i(addr_width+2 downto offset_width+index_width+3);
tags_gen : for i in 0 to assoc-1 generate 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); tags(i) <= cc_tag_rd_data((i+1)*tag_width-1 downto i*tag_width);
end generate; end generate;
cc_rd_addr <= adr_index; cc_rd_addr <= mfi_index when mfi = '1' else
adr_index;
tag_compare : for i in 0 to assoc-1 generate 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 adr_tag_eq(i) <= cc_valid_rd_data(i) when tags(i) = adr_tag else
@@ -309,7 +327,7 @@ begin
adr_tag_eq_num <= to_unsigned(0,1) when adr_tag_eq(0) = '1' else 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 to_unsigned(1,1) when adr_tag_eq(1) = '1' else
(others => dontcare); (others => dontcare);
eject_num <= adr_tag_eq_num when user_cc = '1' else eject_num <= mfi_num when mfi = '1' else
to_unsigned(0,1) when lru_eq0(0) = '1' else to_unsigned(0,1) when lru_eq0(0) = '1' else
to_unsigned(1,1) when lru_eq0(1) = '1' else to_unsigned(1,1) when lru_eq0(1) = '1' else
to_unsigned(0,1); to_unsigned(0,1);
@@ -320,7 +338,7 @@ begin
to_unsigned(2,2) when adr_tag_eq(2) = '1' else to_unsigned(2,2) when adr_tag_eq(2) = '1' else
to_unsigned(3,2) when adr_tag_eq(3) = '1' else to_unsigned(3,2) when adr_tag_eq(3) = '1' else
(others => dontcare); (others => dontcare);
eject_num <= adr_tag_eq_num when user_cc = '1' else eject_num <= mfi_num when mfi = '1' else
to_unsigned(0,2) when lru_eq0(0) = '1' else to_unsigned(0,2) when lru_eq0(0) = '1' else
to_unsigned(1,2) when lru_eq0(1) = '1' else to_unsigned(1,2) when lru_eq0(1) = '1' else
to_unsigned(2,2) when lru_eq0(2) = '1' else to_unsigned(2,2) when lru_eq0(2) = '1' else
@@ -329,6 +347,7 @@ begin
end generate; 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)); 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)); eject_dirty <= cc_dirty_rd_data(to_integer(eject_num)) and cc_valid_rd_data(to_integer(eject_num));
-- Offset counter -- Offset counter
@@ -345,6 +364,35 @@ begin
end if; end if;
end process mem_offset_ctr; 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 wb_ddr_ctrl_wb_sc_fe_fsm_inst: wb_ddr_ctrl_wb_sc_fe_fsm
generic map ( generic map (
line_size => line_size, line_size => line_size,
@@ -363,13 +411,19 @@ begin
adr_tag_eq => adr_tag_eq, adr_tag_eq => adr_tag_eq,
eject_dirty => eject_dirty, eject_dirty => eject_dirty,
mem_offset => mem_offset_dly, mem_offset => mem_offset_dly,
mfi_index => mfi_index,
user_cc_req_flush => user_cc_req_flush, user_cc_req_flush => user_cc_req_flush,
user_cc_req_inval => user_cc_req_inval, user_cc_req_inval => user_cc_req_inval,
user_cc_read => user_cc_read, user_cc_req_none => user_cc_req_none,
adr_tag_eq_num_dirty => adr_tag_eq_num_dirty, adr_tag_eq_num_dirty => adr_tag_eq_num_dirty,
mem_ack => mem_ack, 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, ack_o => wbs_o.ack_o,
update_lru => update_lru, update_lru => update_lru,
set_clean => set_clean,
set_dirty => set_dirty, set_dirty => set_dirty,
set_valid => set_valid, set_valid => set_valid,
set_invalid => set_invalid, set_invalid => set_invalid,
@@ -378,19 +432,25 @@ begin
cache_to_mem => cache_to_mem, cache_to_mem => cache_to_mem,
mem_rdrq => mem_rdrq_int, mem_rdrq => mem_rdrq_int,
mem_wrrq => mem_wrrq_int, mem_wrrq => mem_wrrq_int,
user_cc_ack_o => wbs_cc_o.ack_o, mfi => mfi,
user_cc => user_cc); user_cc_ack_o => wbs_cc_o.ack_o);
mem_rdrq <= mem_rdrq_int; mem_rdrq <= mem_rdrq_int;
mem_wrrq <= mem_wrrq_int; mem_wrrq <= mem_wrrq_int;
user_cc_req_flush <= user_cc_req_flush <=
'1' when wbs_cc_i.cyc_i = '1' and wbs_cc_i.stb_i = '1' and wbs_cc_i.we_i = '1' and wbs_cc_i.adr_i(2) = '0' else 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' and wbs_cc_i.adr_i(2) = '0') else
'0'; '0';
user_cc_req_inval <= user_cc_req_inval <=
'1' when wbs_cc_i.cyc_i = '1' and wbs_cc_i.stb_i = '1' and wbs_cc_i.we_i = '1' and wbs_cc_i.adr_i(2) = '1' else 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' and wbs_cc_i.adr_i(2) = '0') else
'0'; '0';
user_cc_read <= wbs_cc_i.cyc_i and wbs_cc_i.stb_i and not wbs_cc_i.we_i; 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.adr_i(2) /= '0' or wbs_cc_i.dat_i(1 downto 0) = "00")) else
'0';
wbs_cc_o.dat_o <= (others => '0'); wbs_cc_o.dat_o <= (others => '0');
end Behavioral; end Behavioral;

View File

@@ -54,15 +54,20 @@ entity wb_ddr_ctrl_wb_sc_fe_fsm is
adr_tag_eq : in std_logic_vector(assoc-1 downto 0); adr_tag_eq : in std_logic_vector(assoc-1 downto 0);
eject_dirty : in std_logic; eject_dirty : in std_logic;
mem_offset : in unsigned(line_size_ln2-1 downto 0); 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; adr_tag_eq_num_dirty : in std_logic;
user_cc_req_flush : in std_logic; user_cc_req_flush : in std_logic;
user_cc_req_inval : in std_logic; user_cc_req_inval : in std_logic;
user_cc_read : in std_logic; user_cc_req_none : in std_logic;
mem_ack : 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; ack_o : out std_logic;
update_lru : out std_logic := '0'; update_lru : out std_logic := '0';
set_dirty : out std_logic := '0'; set_dirty : out std_logic := '0';
set_clean : out std_logic := '0';
set_valid : out std_logic := '0'; set_valid : out std_logic := '0';
set_invalid : out std_logic := '0'; set_invalid : out std_logic := '0';
cache_write : out std_logic := '0'; cache_write : out std_logic := '0';
@@ -70,14 +75,14 @@ entity wb_ddr_ctrl_wb_sc_fe_fsm is
cache_to_mem : out std_logic := '0'; cache_to_mem : out std_logic := '0';
mem_rdrq : out std_logic := '0'; mem_rdrq : out std_logic := '0';
mem_wrrq : out std_logic := '0'; mem_wrrq : out std_logic := '0';
user_cc : out std_logic := '0'; mfi : out std_logic := '0';
user_cc_ack_o : out std_logic := '0' user_cc_ack_o : out std_logic := '0'
); );
end wb_ddr_ctrl_wb_sc_fe_fsm; end wb_ddr_ctrl_wb_sc_fe_fsm;
architecture Behavioral of wb_ddr_ctrl_wb_sc_fe_fsm is 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, type states is (S_IDLE, S_WRITEBACK1, S_WRITEBACK2, S_FETCH1, S_FETCH2, S_WAIT, S_WAIT_FETCH,
S_USER_CC_INIT, S_USER_WRITEBACK1, S_USER_WRITEBACK2); S_MFI, S_MFI_WRITEBACK1, S_MFI_WRITEBACK2, S_MFI_WAIT);
signal state : states := S_IDLE; signal state : states := S_IDLE;
begin begin
@@ -87,6 +92,7 @@ begin
ack_o <= '0'; ack_o <= '0';
update_lru <= '0'; update_lru <= '0';
set_dirty <= '0'; set_dirty <= '0';
set_clean <= '0';
set_valid <= '0'; set_valid <= '0';
set_invalid <= '0'; set_invalid <= '0';
cache_write <= '0'; cache_write <= '0';
@@ -94,14 +100,17 @@ begin
cache_to_mem <= '0'; cache_to_mem <= '0';
mem_rdrq <= '0'; mem_rdrq <= '0';
mem_wrrq <= '0'; mem_wrrq <= '0';
user_cc <= '0'; mfi <= '0';
user_cc_ack_o <= '0'; user_cc_ack_o <= '0';
case state is case state is
when S_IDLE => when S_IDLE =>
if user_cc_req_flush = '1' or user_cc_req_inval = '1' then if user_cc_req_flush = '1' or user_cc_req_inval = '1' then
user_cc <= '1'; mfi <= '1';
state <= S_USER_CC_INIT; 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 elsif cyc_i = '1' and stb_i = '1' then
if we_i = '1' then if we_i = '1' then
if to_integer(unsigned(adr_tag_eq)) = 0 then if to_integer(unsigned(adr_tag_eq)) = 0 then
@@ -142,8 +151,6 @@ begin
state <= S_WAIT; state <= S_WAIT;
end if; end if;
end if; end if;
elsif user_cc_read = '1' then
user_cc_ack_o <= '1';
end if; end if;
when S_WAIT => when S_WAIT =>
state <= S_IDLE; state <= S_IDLE;
@@ -169,53 +176,72 @@ begin
cache_from_mem <= '1'; cache_from_mem <= '1';
mem_rdrq <= '1'; mem_rdrq <= '1';
state <= S_FETCH1; state <= S_FETCH1;
when S_USER_CC_INIT => when S_MFI =>
user_cc <= '1'; mfi <= '1';
if user_cc_req_inval = '1' then if ((user_cc_req_flush = '0' or to_integer(unsigned(cc_valid and cc_dirty)) = 0) and
if to_integer(unsigned(adr_tag_eq)) = 0 then (user_cc_req_inval = '0' or to_integer(unsigned(cc_valid)) = 0)) then
-- address not in cache, nothing to invalidate -- nothing to do for this set or done with it
if mfi_index = lines/assoc-1 then
user_cc_ack_o <= '1'; user_cc_ack_o <= '1';
state <= S_WAIT; state <= S_WAIT;
else end if;
if adr_tag_eq_num_dirty = '1' then else
-- line is dirty, flush first 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'; cache_to_mem <= '1';
mem_wrrq <= '1'; mem_wrrq <= '1';
state <= S_USER_WRITEBACK1; state <= S_MFI_WRITEBACK1;
else
set_invalid <= '1';
user_cc_ack_o <= '1';
state <= S_WAIT;
end if; end if;
elsif user_cc_req_inval = '1' then
set_invalid <= '1';
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; end if;
when S_USER_WRITEBACK1 =>
user_cc <= '1'; --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'; cache_to_mem <= '1';
state <= S_USER_WRITEBACK2; state <= S_MFI_WRITEBACK2;
when S_USER_WRITEBACK2 => when S_MFI_WRITEBACK2 =>
user_cc <= '1'; mfi <= '1';
cache_to_mem <= '1'; cache_to_mem <= '1';
if mem_offset = line_size-1 and mem_ack = '1' then if mem_offset = line_size-1 and mem_ack = '1' then
cache_to_mem <= '0'; cache_to_mem <= '0';
if user_cc_req_inval = '1' then set_clean <= '1';
set_invalid <= '1'; state <= S_MFI_WAIT;
end if;
user_cc_ack_o <= '1';
state <= S_WAIT;
end if; end if;
when S_MFI_WAIT =>
mfi <= '1';
state <= S_MFI;
end case; end case;
end if; end if;
end process cache_ctrl; end process cache_ctrl;

View File

@@ -6,7 +6,7 @@
-- Author : <Matthias@MATTHIAS-PC> -- Author : <Matthias@MATTHIAS-PC>
-- Company : -- Company :
-- Created : 2013-03-03 -- Created : 2013-03-03
-- Last update: 2013-03-08 -- Last update: 2013-03-19
-- Platform : -- Platform :
-- Standard : VHDL'87 -- Standard : VHDL'87
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
@@ -45,7 +45,8 @@ architecture testbench of wb_ddr_ctrl_wb_sc_fe_tb is
line_size_ln2 : integer; line_size_ln2 : integer;
lines_ln2 : integer; lines_ln2 : integer;
assoc_ln2 : integer; assoc_ln2 : integer;
addr_width : integer); addr_width : integer;
dontcare : std_logic);
port ( port (
clk_i : in std_logic; clk_i : in std_logic;
rst_i : in std_logic; rst_i : in std_logic;
@@ -97,7 +98,8 @@ begin -- testbench
line_size_ln2 => line_size_ln2, line_size_ln2 => line_size_ln2,
lines_ln2 => lines_ln2, lines_ln2 => lines_ln2,
assoc_ln2 => assoc_ln2, assoc_ln2 => assoc_ln2,
addr_width => addr_width) addr_width => addr_width,
dontcare => '0')
port map ( port map (
clk_i => clk_i, clk_i => clk_i,
rst_i => rst_i, rst_i => rst_i,
@@ -282,8 +284,8 @@ begin -- testbench
wbs_cc_i.cyc_i <= '1'; wbs_cc_i.cyc_i <= '1';
wbs_cc_i.stb_i <= '1'; wbs_cc_i.stb_i <= '1';
wbs_cc_i.we_i <= '1'; wbs_cc_i.we_i <= '1';
wbs_cc_i.adr_i <= "1"; wbs_cc_i.adr_i <= "0";
wbs_cc_i.dat_i <= x"00000840"; wbs_cc_i.dat_i <= x"00000001";
wbs_cc_i.sel_i <= "1111"; wbs_cc_i.sel_i <= "1111";
wait until rising_edge(clk_i); wait until rising_edge(clk_i);
while wbs_cc_o.ack_o = '0' loop while wbs_cc_o.ack_o = '0' loop
@@ -314,7 +316,7 @@ begin -- testbench
wbs_cc_i.stb_i <= '1'; wbs_cc_i.stb_i <= '1';
wbs_cc_i.we_i <= '1'; wbs_cc_i.we_i <= '1';
wbs_cc_i.adr_i <= "0"; wbs_cc_i.adr_i <= "0";
wbs_cc_i.dat_i <= x"00000840"; wbs_cc_i.dat_i <= x"00000002";
wbs_cc_i.sel_i <= "1111"; wbs_cc_i.sel_i <= "1111";
wait until rising_edge(clk_i); wait until rising_edge(clk_i);
while wbs_cc_o.ack_o = '0' loop while wbs_cc_o.ack_o = '0' loop

File diff suppressed because it is too large Load Diff