signal sci_reg_i : std_logic;
type sci_ctrl is (IDLE, SCTRL, SCTRL_WAIT, SCTRL_WAIT2, SCTRL_FINISH, GET_WA, GET_WA_WAIT, GET_WA_WAIT2, GET_WA_FINISH);
signal sci_state : sci_ctrl;
+type bus_ctrl is (BUSIDLE, BUSCTRL);
+signal bus_state : bus_ctrl;
+
signal sci_timer : unsigned(12 downto 0) := (others => '0');
signal wa_position : std_logic_vector(15 downto 0);
+signal next_sci_wr : std_logic;
begin
LOC_BUS_RX.addr <= BUS_RX.addr;
LOC_BUS_RX.data <= BUS_RX.data;
-PROC_SCI_CTRL: process
- variable cnt : integer range 0 to 4 := 0;
+PROC_BUS_CTRL: process
begin
wait until rising_edge(CLK);
BUS_TX.ack <= '0';
BUS_TX.nack <= '0';
BUS_TX.unknown <= '0';
- --BUS_TX.rack <= '0';
- --BUS_TX.wack <= '0';
LOC_BUS_RX.read <= '0';
LOC_BUS_RX.write <= '0';
BUS_TX.data <= x"ffffffff";
+
+ case bus_state is
+ when BUSIDLE =>
+ if BUS_RX.read = '1' or BUS_RX.write = '1' then
+ sci_reg_i <= BUS_RX.addr(6) and not BUS_RX.addr(7) and BUS_RX.addr(8);
+ LOC_BUS_RX.read <= BUS_RX.read and BUS_RX.addr(6) and not BUS_RX.addr(7) and BUS_RX.addr(8);
+ LOC_BUS_RX.write <= BUS_RX.write and BUS_RX.addr(6) and not BUS_RX.addr(7) and BUS_RX.addr(8);
+ bus_state <= BUSCTRL;
+ end if;
+ when BUSCTRL =>
+ if sci_reg_i = '1' then
+ LOC_BUS_RX.read <= BUS_RX.read;
+ LOC_BUS_RX.write <= BUS_RX.write;
+ if (LOC_BUS_TX.ack = '1') then
+ bus_state <= BUSIDLE;
+ BUS_TX.data <= LOC_BUS_TX.data;
+ BUS_TX.ack <= '1';
+ BUS_TX.unknown <= LOC_BUS_TX.unknown;
+ end if;
+ elsif sci_reg_i = '0' and sci_state = SCTRL_FINISH then
+ BUS_TX.data(7 downto 0) <= SCI_RDDATA;
+ BUS_TX.data(31 downto 8) <= x"000000";
+ BUS_TX.ack <= '1';
+ bus_state <= BUSIDLE;
+ elsif sci_reg_i = '0' and sci_state = IDLE then
+ BUS_TX.ack <= '1';
+ bus_state <= BUSIDLE;
+ end if;
+ end case;
+end process;
+
+PROC_SCI_CTRL: process
+ variable cnt : integer range 0 to 4 := 0;
+begin
+ wait until rising_edge(CLK);
+
+ SCI_WR <= next_sci_wr;
case sci_state is
when IDLE =>
SCI_SEL <= (others => '0');
- sci_reg_i <= '0';
SCI_RD <= '0';
- SCI_WR <= '0';
+ next_sci_wr <= '0';
sci_timer <= sci_timer + 1;
if BUS_RX.read = '1' or BUS_RX.write = '1' then
SCI_SEL(0) <= not BUS_RX.addr(6) and not BUS_RX.addr(7) and not BUS_RX.addr(8);
SCI_SEL(2) <= not BUS_RX.addr(6) and BUS_RX.addr(7) and not BUS_RX.addr(8);
SCI_SEL(3) <= BUS_RX.addr(6) and BUS_RX.addr(7) and not BUS_RX.addr(8);
SCI_SEL(4) <= not BUS_RX.addr(6) and not BUS_RX.addr(7) and BUS_RX.addr(8);
- sci_reg_i <= BUS_RX.addr(6) and not BUS_RX.addr(7) and BUS_RX.addr(8);
+
SCI_ADDR <= BUS_RX.addr(5 downto 0);
SCI_WRDATA <= BUS_RX.data(7 downto 0);
SCI_RD <= BUS_RX.read and not (BUS_RX.addr(6) and not BUS_RX.addr(7) and BUS_RX.addr(8));
- SCI_WR <= BUS_RX.write and not (BUS_RX.addr(6) and not BUS_RX.addr(7) and BUS_RX.addr(8));
- LOC_BUS_RX.read <= BUS_RX.read and BUS_RX.addr(6) and not BUS_RX.addr(7) and BUS_RX.addr(8);
- LOC_BUS_RX.write <= BUS_RX.write and BUS_RX.addr(6) and not BUS_RX.addr(7) and BUS_RX.addr(8);
- sci_state <= SCTRL;
+ next_sci_wr <= BUS_RX.write and not (BUS_RX.addr(6) and not BUS_RX.addr(7) and BUS_RX.addr(8));
+ sci_state <= SCTRL;
elsif sci_timer(sci_timer'left) = '1' then
sci_timer <= (others => '0');
sci_state <= GET_WA;
end if;
when SCTRL =>
if sci_reg_i = '1' then
- LOC_BUS_RX.read <= BUS_RX.read;
- LOC_BUS_RX.write <= BUS_RX.write;
- SCI_WR <= '0';
+ next_sci_wr <= '0';
SCI_RD <= '0';
- if (LOC_BUS_TX.ack = '1') then
+ if (LOC_BUS_TX.ack = '1' or BUS_STATE = BUSIDLE) then
sci_state <= IDLE;
- BUS_TX.data <= LOC_BUS_TX.data;
- BUS_TX.ack <= '1';
- BUS_TX.unknown <= LOC_BUS_TX.unknown;
end if;
else
sci_state <= SCTRL_WAIT;
when SCTRL_WAIT2 =>
sci_state <= SCTRL_FINISH;
when SCTRL_FINISH =>
- BUS_TX.data(7 downto 0) <= SCI_RDDATA;
- BUS_TX.data(31 downto 8) <= x"000000";
- BUS_TX.ack <= '1';
- SCI_WR <= '0';
+ next_sci_wr <= '0';
SCI_RD <= '0';
sci_state <= IDLE;
end if;
when GET_WA_WAIT =>
sci_state <= GET_WA_WAIT2;
- if BUS_RX.read = '1' or BUS_RX.write = '1' then
- sci_state <= IDLE;
- end if;
when GET_WA_WAIT2 =>
sci_state <= GET_WA_FINISH;
- if BUS_RX.read = '1' or BUS_RX.write = '1' then
- sci_state <= IDLE;
- end if;
when GET_WA_FINISH =>
wa_position(cnt*4+3 downto cnt*4) <= SCI_RDDATA(3 downto 0);
sci_state <= GET_WA;
cnt := cnt + 1;
- if BUS_RX.read = '1' or BUS_RX.write = '1' then
- sci_state <= IDLE;
- end if;
end case;
- if (BUS_RX.read = '1' or BUS_RX.write = '1') and sci_state /= IDLE and sci_reg_i = '0' then
- BUS_TX.nack <= '1';
- BUS_TX.ack <= '0';
- end if;
+-- if (BUS_RX.read = '1' or BUS_RX.write = '1') and sci_state /= IDLE and sci_reg_i = '0' then
+-- BUS_TX.nack <= '1';
+-- BUS_TX.ack <= '0';
+-- end if;
end process;