---------------------------------------------------------------------
-- register and IO access state machine
command_state:
process(rst_n, clk)
begin
if(rst_n = '0') then
user_reg <= (others => '0');
cmdstate <= init;
iostate <= addr_rx;
byte_cnt <= 0;
frame_cnt <= "000000";
ioaddr <= (others => '0');
iodatao <= (others => '0');
iodatai <= (others => '0');
iorwn <= '1';
iosel <= '0';
txdata <= (others => '0');
tx_en <= '0';
realign <= '0';
ctl_reg <= (others => '0');
-- stat_reg <= (others => '0');
elsif(clk'event and clk = '1') then
tx_en <= '0';
realign <= '0';
-- on startup wait for rx to be idle
case cmdstate is
when init =>
if(rxstate = idle) then
cmdstate <= idle;
end if;
-- once in idle state decode the first incoming byte
when idle =>
iosel <= '0';
iorwn <= '1';
byte_cnt <= 0;
if(new_rx = '1') then
if(rx_ddata(7 downto 6) = "10") then
cmdstate <= io_rd;
frame_cnt <= rx_ddata(5 downto 0);
elsif(rx_ddata(7 downto 6) = "11") then
cmdstate <= io_wr;
frame_cnt <= rx_ddata(5 downto 0);
else
case rx_ddata(5 downto 0) is
when "010000" =>
cmdstate <= reg_wr;
when "010001" =>
txdata <= ctl_reg;
tx_en <= '1';
cmdstate <= reg_rd;
when "010100" =>
txdata <= stat_reg;
tx_en <= '1';
cmdstate <= reg_rd;
when "011000" =>
cmdstate <= reg_wr;
when "011001" =>
txdata <= user_reg;
tx_en <= '1';
cmdstate <= reg_rd;
when others =>
null;
end case;
end if;
end if;
-- wait here till tx is done writing out register
when reg_rd =>
if(tx_done = '1') then
cmdstate <= idle;
end if;
-- write next data into the addressed writeable register
when reg_wr =>
if(new_rx = '1') then
case rx_ddata(5 downto 0) is
when "010000" =>
ctl_reg <= rx_wdata;
ctl_reg(0) <= '0';
realign <= rx_wdata(0);
when "011000" =>
user_reg <= rx_wdata;
when others =>
null;
end case;
cmdstate <= idle;
end if;
-- IO read cycle
when io_rd =>
case iostate is
when addr_rx =>
if(new_rx = '1') then
case byte_cnt is
when 0 =>
ioaddr(15 downto 8) <= rx_wdata;
byte_cnt <= byte_cnt + 1;
when 1 =>
ioaddr(7 downto 0) <= rx_wdata;
byte_cnt <= byte_cnt + 1;
iosel <= '1';
iorwn <= '1';
iostate <= ack_wait;
when others =>
null;
end case;
end if;
when ack_wait =>
if(if_in.ack = '1') then
iodatai <= if_in.data;
iostate <= tx_start;
byte_cnt <= 0;
end if;
when tx_start =>
iosel <= '0';
if(byte_cnt = 0) then
txdata <= iodatai(15 downto 8);
tx_en <= '1';
iostate <= tx_wait;
else
txdata <= iodatai(7 downto 0);
tx_en <= '1';
iostate <= tx_wait;
end if;
when tx_wait =>
if(tx_done = '1') then
if(byte_cnt = 0) then
iostate <= tx_start;
byte_cnt <= byte_cnt + 1;
elsif(frame_cnt = "000000") then
iostate <= addr_rx;
cmdstate <= idle;
else
byte_cnt <= 0;
ioaddr(15 downto 0) <= ioaddr(15 downto 0) + 1;
frame_cnt <= frame_cnt - "000001";
iostate <= ack_wait;
iosel <= '1';
end if;
end if;
end case;
-- and IO write cycle, no wait for ack
when io_wr =>
iosel <= '0';
if(new_rx = '1') then
case byte_cnt is
when 0 =>
ioaddr(15 downto 8) <= rx_wdata;
byte_cnt <= byte_cnt + 1;
when 1 =>
ioaddr(7 downto 0) <= rx_wdata;
byte_cnt <= byte_cnt + 1;
when 2 =>
iodatao(15 downto 8) <= rx_wdata;
byte_cnt <= byte_cnt + 1;
when 3 =>
iodatao(7 downto 0) <= rx_wdata;
iosel <= '1';
iorwn <= '0';
if(frame_cnt = "000000") then
cmdstate <= idle;
else
byte_cnt <= byte_cnt + 1;
frame_cnt <= frame_cnt - "000001";
end if;
when 4 =>
iodatao(15 downto 8) <= rx_wdata;
byte_cnt <= byte_cnt + 1;
ioaddr(15 downto 0) <= ioaddr(15 downto 0) + 1;
when 5 =>
iodatao(7 downto 0) <= rx_wdata;
iosel <= '1';
iorwn <= '0';
-- byte_cnt <= 4;
if(frame_cnt = "000000") then
cmdstate <= idle;
else
frame_cnt <= frame_cnt - "000001";
byte_cnt <= 4;
end if;
when 6 =>
when 7 =>
when others =>
end case;
end if;
end case;
end if;
end process command_state;
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?