mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-01-11 23:43:15 +00:00
Merge pull request #413 from ozbenh/fix-io-bridge-qw-store
soc: Fix issues with 64-bit stores to IO bridge
This commit is contained in:
commit
432d9f3150
55
soc.vhdl
55
soc.vhdl
@ -476,6 +476,8 @@ begin
|
||||
variable end_cyc : std_ulogic;
|
||||
variable slave_io : slave_io_type;
|
||||
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
|
||||
if rising_edge(system_clk) then
|
||||
do_cyc := '0';
|
||||
@ -488,6 +490,8 @@ begin
|
||||
end_cyc := '1';
|
||||
has_top := false;
|
||||
has_bot := false;
|
||||
dat_latch := (others => '0');
|
||||
sel_latch := (others => '0');
|
||||
else
|
||||
case state is
|
||||
when IDLE =>
|
||||
@ -497,7 +501,11 @@ begin
|
||||
-- Do we have a cycle ?
|
||||
if wb_io_in.cyc = '1' and wb_io_in.stb = '1' then
|
||||
-- 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';
|
||||
|
||||
-- Start cycle downstream
|
||||
@ -512,21 +520,22 @@ begin
|
||||
has_top := wb_io_in.sel(7 downto 4) /= "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
|
||||
-- send the top word down. XXX Split the actual mux out
|
||||
-- and only generate a control signal.
|
||||
-- send the top word down.
|
||||
if has_bot then
|
||||
if wb_io_in.we = '1' then
|
||||
wb_sio_out.dat <= wb_io_in.dat(31 downto 0);
|
||||
end if;
|
||||
-- Always update out.dat, it doesn't matter if we
|
||||
-- update it on reads and it saves mux
|
||||
wb_sio_out.dat <= wb_io_in.dat(31 downto 0);
|
||||
wb_sio_out.sel <= wb_io_in.sel(3 downto 0);
|
||||
|
||||
-- Wait for ack
|
||||
state := WAIT_ACK_BOT;
|
||||
else
|
||||
if wb_io_in.we = '1' then
|
||||
wb_sio_out.dat <= wb_io_in.dat(63 downto 32);
|
||||
end if;
|
||||
wb_sio_out.dat <= wb_io_in.dat(63 downto 32);
|
||||
wb_sio_out.sel <= wb_io_in.sel(7 downto 4);
|
||||
|
||||
-- Bump address
|
||||
@ -544,18 +553,14 @@ begin
|
||||
|
||||
-- Handle ack
|
||||
if wb_sio_in.ack = '1' then
|
||||
-- If it's a read, latch the data
|
||||
if wb_sio_out.we = '0' then
|
||||
wb_io_out.dat(31 downto 0) <= wb_sio_in.dat;
|
||||
end if;
|
||||
-- Always latch the data, it doesn't matter if it was
|
||||
-- a write and it saves a mux
|
||||
wb_io_out.dat(31 downto 0) <= wb_sio_in.dat;
|
||||
|
||||
-- Do we have a "top" part as well ?
|
||||
if has_top then
|
||||
-- Latch data & sel
|
||||
if wb_io_in.we = '1' then
|
||||
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.dat <= dat_latch;
|
||||
wb_sio_out.sel <= sel_latch;
|
||||
|
||||
-- Bump address and set STB
|
||||
wb_sio_out.adr(0) <= '1';
|
||||
@ -583,10 +588,9 @@ begin
|
||||
|
||||
-- Handle ack
|
||||
if wb_sio_in.ack = '1' then
|
||||
-- If it's a read, latch the data
|
||||
if wb_sio_out.we = '0' then
|
||||
wb_io_out.dat(63 downto 32) <= wb_sio_in.dat;
|
||||
end if;
|
||||
-- Always latch the data, it doesn't matter if it was
|
||||
-- a write and it saves a mux
|
||||
wb_io_out.dat(63 downto 32) <= wb_sio_in.dat;
|
||||
|
||||
-- We are done, ack up, clear cyc downstram
|
||||
end_cyc := '1';
|
||||
@ -603,6 +607,13 @@ begin
|
||||
|
||||
-- Create individual registered cycle signals for the wishbones
|
||||
-- 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
|
||||
io_cycle_none <= '0';
|
||||
io_cycle_syscon <= '0';
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user