Merge pull request #413 from ozbenh/fix-io-bridge-qw-store

soc: Fix issues with 64-bit stores to IO bridge
pull/415/head
Michael Neuling 2 years ago committed by GitHub
commit 432d9f3150
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -476,6 +476,8 @@ begin
variable end_cyc : std_ulogic; variable end_cyc : std_ulogic;
variable slave_io : slave_io_type; variable slave_io : slave_io_type;
variable match : std_ulogic_vector(31 downto 12); variable match : std_ulogic_vector(31 downto 12);
variable dat_latch : std_ulogic_vector(31 downto 0);
variable sel_latch : std_ulogic_vector(3 downto 0);
begin begin
if rising_edge(system_clk) then if rising_edge(system_clk) then
do_cyc := '0'; do_cyc := '0';
@ -488,6 +490,8 @@ begin
end_cyc := '1'; end_cyc := '1';
has_top := false; has_top := false;
has_bot := false; has_bot := false;
dat_latch := (others => '0');
sel_latch := (others => '0');
else else
case state is case state is
when IDLE => when IDLE =>
@ -497,7 +501,11 @@ begin
-- Do we have a cycle ? -- Do we have a cycle ?
if wb_io_in.cyc = '1' and wb_io_in.stb = '1' then if wb_io_in.cyc = '1' and wb_io_in.stb = '1' then
-- Stall master until we are done, we are't (yet) pipelining -- Stall master until we are done, we are't (yet) pipelining
-- this, it's all slow IOs. -- this, it's all slow IOs. Note: The current cycle has
-- already been accepted as "stall" was 0, this only blocks
-- the next one. This means that we must latch
-- everything we need from wb_io_in in *this* cycle.
--
wb_io_out.stall <= '1'; wb_io_out.stall <= '1';


-- Start cycle downstream -- Start cycle downstream
@ -512,21 +520,22 @@ begin
has_top := wb_io_in.sel(7 downto 4) /= "0000"; has_top := wb_io_in.sel(7 downto 4) /= "0000";
has_bot := wb_io_in.sel(3 downto 0) /= "0000"; has_bot := wb_io_in.sel(3 downto 0) /= "0000";


-- Remember the top word as it might be needed later
dat_latch := wb_io_in.dat(63 downto 32);
sel_latch := wb_io_in.sel(7 downto 4);

-- If we have a bottom word, handle it first, otherwise -- If we have a bottom word, handle it first, otherwise
-- send the top word down. XXX Split the actual mux out -- send the top word down.
-- and only generate a control signal.
if has_bot then if has_bot then
if wb_io_in.we = '1' then -- Always update out.dat, it doesn't matter if we
wb_sio_out.dat <= wb_io_in.dat(31 downto 0); -- update it on reads and it saves mux
end if; wb_sio_out.dat <= wb_io_in.dat(31 downto 0);
wb_sio_out.sel <= wb_io_in.sel(3 downto 0); wb_sio_out.sel <= wb_io_in.sel(3 downto 0);


-- Wait for ack -- Wait for ack
state := WAIT_ACK_BOT; state := WAIT_ACK_BOT;
else else
if wb_io_in.we = '1' then wb_sio_out.dat <= wb_io_in.dat(63 downto 32);
wb_sio_out.dat <= wb_io_in.dat(63 downto 32);
end if;
wb_sio_out.sel <= wb_io_in.sel(7 downto 4); wb_sio_out.sel <= wb_io_in.sel(7 downto 4);


-- Bump address -- Bump address
@ -544,18 +553,14 @@ begin


-- Handle ack -- Handle ack
if wb_sio_in.ack = '1' then if wb_sio_in.ack = '1' then
-- If it's a read, latch the data -- Always latch the data, it doesn't matter if it was
if wb_sio_out.we = '0' then -- a write and it saves a mux
wb_io_out.dat(31 downto 0) <= wb_sio_in.dat; wb_io_out.dat(31 downto 0) <= wb_sio_in.dat;
end if;


-- Do we have a "top" part as well ? -- Do we have a "top" part as well ?
if has_top then if has_top then
-- Latch data & sel wb_sio_out.dat <= dat_latch;
if wb_io_in.we = '1' then wb_sio_out.sel <= sel_latch;
wb_sio_out.dat <= wb_io_in.dat(63 downto 32);
end if;
wb_sio_out.sel <= wb_io_in.sel(7 downto 4);


-- Bump address and set STB -- Bump address and set STB
wb_sio_out.adr(0) <= '1'; wb_sio_out.adr(0) <= '1';
@ -583,10 +588,9 @@ begin


-- Handle ack -- Handle ack
if wb_sio_in.ack = '1' then if wb_sio_in.ack = '1' then
-- If it's a read, latch the data -- Always latch the data, it doesn't matter if it was
if wb_sio_out.we = '0' then -- a write and it saves a mux
wb_io_out.dat(63 downto 32) <= wb_sio_in.dat; wb_io_out.dat(63 downto 32) <= wb_sio_in.dat;
end if;


-- We are done, ack up, clear cyc downstram -- We are done, ack up, clear cyc downstram
end_cyc := '1'; end_cyc := '1';
@ -603,6 +607,13 @@ begin


-- Create individual registered cycle signals for the wishbones -- Create individual registered cycle signals for the wishbones
-- going to the various peripherals -- going to the various peripherals
--
-- Note: This needs to happen on the cycle matching state = IDLE,
-- as wb_io_in content can only be relied upon on that one cycle.
-- This works here because do_cyc is a variable, not a signal, and
-- thus here we observe the value set above in the state machine
-- on the same cycle rather than the next one.
--
if do_cyc = '1' or end_cyc = '1' then if do_cyc = '1' or end_cyc = '1' then
io_cycle_none <= '0'; io_cycle_none <= '0';
io_cycle_syscon <= '0'; io_cycle_syscon <= '0';

Loading…
Cancel
Save