Commit dfd5bbd5 authored by kblantos's avatar kblantos

First working mt_profip_translator. MOSI side works even in more than spi freq…

First working mt_profip_translator. MOSI side works even in more than spi freq 5MHz but MISO is working up to 5MHz
parent abed58e8
......@@ -9,6 +9,6 @@ files = [
"masterfip_wbgen2_pkg.vhd",
"wf_package.vhd",
"spi_slave.vhd",
"mt_profip_translator.vhd"
"mt_profip_translator.vhd",
]
......@@ -76,7 +76,7 @@ architecture rtl of mt_profip_translator is
type t_wr_state is (IDLE, BASIC_INFO, HEADER_1, HEADER_2, WAIT_HEADER,
DATA_1, DATA_2, WAIT_DATA, CHECKSUM);
type t_rd_state is (IDLE, RD_HEADER, PRE_LOAD, LOAD_HWORD, LOAD_LWORD, DATA, END_OF_FRAME);
type t_rd_state is (IDLE, WAIT_HEADER, RD_HEADER, PRE_LOAD, LOAD_HWORD, LOAD_LWORD, DATA, END_OF_FRAME);
signal s_wr_state : t_wr_state;
signal s_rd_state : t_rd_state;
......@@ -94,6 +94,10 @@ architecture rtl of mt_profip_translator is
signal wr_data : std_logic_vector(15 downto 0);
signal spi_data_valid_i : std_logic;
signal spi_data_valid_o : std_logic;
signal s_dv_o : std_logic;
signal s_ready : std_logic;
signal s_operation : std_logic;
signal s_oper_en : std_logic;
signal valid : std_logic;
signal fail : std_logic;
signal rd_en : std_logic;
......@@ -144,7 +148,9 @@ begin
data_o => spi_mosi_data,
data_valid_o => spi_data_valid_o,
ready_o => spi_ready,
busy_o => spi_busy);
busy_o => spi_busy,
operation_o => s_operation
);
-- Asynchronous FIFO used for fixing the CDC between
-- SPI Slave and Translator, because there are both
......@@ -441,48 +447,66 @@ begin
rmq_src_o.error <= fail;
-- Write enable of the MOSI FIFO
mosi_wr_en <= '1' when (spi_data_valid_o = '1' and mosi_fifo_wr_full ='0') else '0'; -- we are using the output valid from SPI Slave (it is in the clk domain of MT)
mosi_wr_en <= '1' when (s_dv_o = '1' and mosi_fifo_wr_full ='0') else '0'; -- we are using the output valid from SPI Slave (it is in the clk domain of MT)
-- Read enable of the MOSI FIFO
mosi_rd_en <= '1' when (mosi_fifo_rd_empty = '0' and rmq_src_i.ready = '1') else '0';
-- Capture the positive edge of the spi_data_valid_o
cmp_dv_o_edge_detect : entity work.gc_edge_detect
generic map (
g_ASYNC_RST => false,
g_PULSE_EDGE => "positive",
g_CLOCK_EDGE => "positive")
port map (
clk_i => clk_i,
rst_n_i => rst_n_i,
data_i => spi_data_valid_o,
pulse_o => s_dv_o);
----------------------------------------------------------------------------
-- TX: MT (RMQ) --> MASTERFIP TRANSLATOR
----------------------------------------------------------------------------
-- FSM for reading data from RMQ. The basic idea is that we read the data from
-- the MISO FIFO that it is already stored. If it is a header data
p_rd_fsm : process(clk_i, rst_n_i) --clk_ref_i, rst_n_i)
p_rd_fsm : process(clk_i, rst_n_i)
begin
if rst_n_i = '0' then
s_rd_state <= IDLE;
rd_en <= '0';
miso_data_reg <= (others=>'0');
s_data_valid <= '0';
miso_last <= '0';
elsif rising_edge(clk_i) then --clk_ref_i) then
elsif rising_edge(clk_i) then
case s_rd_state is
----------------------------------------------------------------
--! STATE IDLE
when IDLE =>
miso_last <= '0';
if spi_ready = '1' and miso_fifo_rd_empty = '0' and wr_control(0) = '1' and miso_fifo_data_out(35 downto 32) = "1100" then
rd_en <= '1';
if s_oper_en = '1' then
s_rd_state <= WAIT_HEADER;
else
s_rd_state <= IDLE;
end if;
----------------------------------------------------------------
--! STATE WAIT_HEADER
when WAIT_HEADER =>
if s_ready = '1' and miso_fifo_rd_empty = '0' and miso_fifo_data_out(35 downto 32) = "1100" then
s_data_valid <= '1';
miso_data_reg <= miso_fifo_data_out(31 downto 0);
s_rd_state <= RD_HEADER;
else
miso_data_reg <= miso_data_reg;
s_data_valid <= '0';
rd_en <= '0';
s_rd_state <= IDLE;
s_rd_state <= WAIT_HEADER;
end if;
----------------------------------------------------------------
--! STATE RD_HEADER
when RD_HEADER =>
rd_en <= '0';
s_data_valid <= '0';
s_rd_state <= PRE_LOAD;
......@@ -491,10 +515,8 @@ begin
when PRE_LOAD =>
s_data_valid <= '0';
if miso_fifo_rd_empty = '0' then
rd_en <= '1';
s_rd_state <= LOAD_HWORD;
else
rd_en <= '0';
s_rd_state <= PRE_LOAD;
end if;
......@@ -503,7 +525,6 @@ begin
when LOAD_HWORD =>
s_data_valid <= '0';
if miso_fifo_rd_empty = '0' then
rd_en <= '1';
if miso_fifo_data_out(34) = '1' and miso_fifo_data_out(32) = '0' then
miso_data_reg(31 downto 16) <= miso_fifo_data_out(15 downto 0);
s_rd_state <= LOAD_LWORD;
......@@ -513,7 +534,6 @@ begin
s_rd_state <= IDLE;
end if;
else
rd_en <= '0';
s_rd_state <= LOAD_HWORD;
end if;
......@@ -521,7 +541,6 @@ begin
--! STATE LOAD_LWORD
when LOAD_LWORD =>
if miso_fifo_rd_empty = '0' then
rd_en <= '1';
if miso_fifo_data_out(34) = '1' and miso_fifo_data_out(32) = '0' then -- valid & !error
miso_data_reg(15 downto 0) <= miso_fifo_data_out(15 downto 0);
if miso_fifo_data_out(33) = '1' then -- if last
......@@ -533,15 +552,13 @@ begin
s_rd_state <= IDLE;
end if;
else
rd_en <= '0';
s_rd_state <= LOAD_LWORD;
end if;
----------------------------------------------------------------
--! STATE DATA
when DATA =>
rd_en <= '0';
if spi_ready = '1' then
if s_ready = '1' then
s_data_valid <= '1';
if miso_last = '1' then
s_rd_state <= END_OF_FRAME;
......@@ -555,9 +572,9 @@ begin
----------------------------------------------------------------
--! STATE END_OF_FRAME
when END_OF_FRAME =>
rd_en <= '0';
s_data_valid <= '0';
miso_last <= '0';
miso_data_reg <= (others=>'0');
if spi_cs_n_i = '1' then
s_rd_state <= IDLE;
else
......@@ -568,7 +585,6 @@ begin
--! STATE DEFAULT
when others =>
s_rd_state <= IDLE;
rd_en <= '0';
----------------------------------------------------------------
end case;
......@@ -582,9 +598,27 @@ begin
-- Write enable of the MISO FIFO
miso_wr_en <= '1' when (rmq_snk_i.valid = '1' and rmq_snk_i.error = '0' and miso_fifo_wr_full = '0') else '0';
rd_en <= '1' when (s_rd_state = RD_HEADER or s_rd_state = LOAD_HWORD or s_rd_state = LOAD_LWORD) else '0';
-- Read enable of the MISO FIFO
miso_rd_en <= rd_en;
spi_miso_data <= miso_data_reg;
spi_miso_data <= miso_data_reg when s_ready = '1';
spi_data_valid_i <= s_data_valid;
s_oper_en <= s_operation when (s_rd_state = IDLE and s_wr_state = IDLE) else '0' when s_rd_state = END_OF_FRAME;
-- Capture the positive edge of the spi-ready
cmp_ready_o_edge_detect : entity work.gc_edge_detect
generic map (
g_ASYNC_RST => false,
g_PULSE_EDGE => "positive",
g_CLOCK_EDGE => "positive")
port map (
clk_i => clk_i,
rst_n_i => rst_n_i,
data_i => spi_ready,
pulse_o => s_ready);
end architecture rtl;
......@@ -67,7 +67,8 @@ entity spi_slave is
data_valid_o : out std_logic;
-- Flag
busy_o : out std_logic;
ready_o : out std_logic
ready_o : out std_logic;
operation_o : out std_logic
);
end entity spi_slave;
......@@ -200,6 +201,8 @@ begin
data_o <= data_reg_o;
data_valid_o <= s_data_valid;
operation_o <= data_reg_o(0) when mosi_cnt = 8 else '0';
----------------------------------------------------------------------------
-- MISO
----------------------------------------------------------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment