Line 117... |
Line 117... |
-- Streamlined port names and indentation blocks.
|
-- Streamlined port names and indentation blocks.
|
-- 2011/08/01 v2.01.0115 [JD] Adjusted 'do_valid_o' pulse width to be 2 'clk_i', as in the master core.
|
-- 2011/08/01 v2.01.0115 [JD] Adjusted 'do_valid_o' pulse width to be 2 'clk_i', as in the master core.
|
-- Simulated in iSim with the master core for continuous transmission mode.
|
-- Simulated in iSim with the master core for continuous transmission mode.
|
-- 2011/08/02 v2.02.0120 [JD] Added mux for MISO at reset state, to output di(N-1) at start. This fixed a bug in first bit.
|
-- 2011/08/02 v2.02.0120 [JD] Added mux for MISO at reset state, to output di(N-1) at start. This fixed a bug in first bit.
|
-- The master and slave cores were verified in FPGA with continuous transmission, for all SPI modes.
|
-- The master and slave cores were verified in FPGA with continuous transmission, for all SPI modes.
|
|
-- 2011/08/04 v2.02.0121 [JD] Changed minor comment bugs in the combinatorial fsm logic.
|
--
|
--
|
--
|
--
|
-----------------------------------------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------------------------------------
|
-- TODO
|
-- TODO
|
-- ====
|
-- ====
|
Line 334... |
Line 335... |
wr_ack_next <= wr_ack_reg; -- write enable acknowledge
|
wr_ack_next <= wr_ack_reg; -- write enable acknowledge
|
di_req_next <= di_req_reg; -- data input request
|
di_req_next <= di_req_reg; -- data input request
|
state_next <= state_reg; -- fsm control state
|
state_next <= state_reg; -- fsm control state
|
case state_reg is
|
case state_reg is
|
|
|
when (N) =>
|
when (N) => -- deassert 'di_rdy' and stretch do_valid
|
-- stretch do_valid
|
|
wr_ack_next <= '0'; -- acknowledge data in transfer
|
wr_ack_next <= '0'; -- acknowledge data in transfer
|
di_req_next <= '0'; -- prefetch data request: deassert when shifting data
|
di_req_next <= '0'; -- prefetch data request: deassert when shifting data
|
tx_bit_next <= sh_reg(N-1); -- output next MSbit
|
tx_bit_next <= sh_reg(N-1); -- output next MSbit
|
sh_next(N-1 downto 1) <= sh_reg(N-2 downto 0); -- shift inner bits
|
sh_next(N-1 downto 1) <= sh_reg(N-2 downto 0); -- shift inner bits
|
sh_next(0) <= rx_bit_next; -- shift in rx bit into LSb
|
sh_next(0) <= rx_bit_next; -- shift in rx bit into LSb
|
state_next <= state_reg - 1; -- update next state at each sck pulse
|
state_next <= state_reg - 1; -- update next state at each sck pulse
|
|
|
when (N-1) downto (PREFETCH+3) =>
|
when (N-1) downto (PREFETCH+3) => -- remove 'do_transfer' and shift bits
|
-- send bit out and shif bit in
|
do_transfer_next <= '0'; -- reset 'do_valid' transfer signal
|
do_transfer_next <= '0'; -- reset transfer signal
|
|
di_req_next <= '0'; -- prefetch data request: deassert when shifting data
|
di_req_next <= '0'; -- prefetch data request: deassert when shifting data
|
wr_ack_next <= '0'; -- remove data load ack for all but the load stages
|
wr_ack_next <= '0'; -- remove data load ack for all but the load stages
|
tx_bit_next <= sh_reg(N-1); -- output next MSbit
|
tx_bit_next <= sh_reg(N-1); -- output next MSbit
|
sh_next(N-1 downto 1) <= sh_reg(N-2 downto 0); -- shift inner bits
|
sh_next(N-1 downto 1) <= sh_reg(N-2 downto 0); -- shift inner bits
|
sh_next(0) <= rx_bit_next; -- shift in rx bit into LSb
|
sh_next(0) <= rx_bit_next; -- shift in rx bit into LSb
|
state_next <= state_reg - 1; -- update next state at each sck pulse
|
state_next <= state_reg - 1; -- update next state at each sck pulse
|
|
|
when (PREFETCH+2) downto 3 =>
|
when (PREFETCH+2) downto 3 => -- raise prefetch 'di_req_o' signal
|
-- raise data prefetch request
|
|
di_req_next <= '1'; -- request data in advance to allow for pipeline delays
|
di_req_next <= '1'; -- request data in advance to allow for pipeline delays
|
wr_ack_next <= '0'; -- remove data load ack for all but the load stages
|
wr_ack_next <= '0'; -- remove data load ack for all but the load stages
|
tx_bit_next <= sh_reg(N-1); -- output next MSbit
|
tx_bit_next <= sh_reg(N-1); -- output next MSbit
|
sh_next(N-1 downto 1) <= sh_reg(N-2 downto 0); -- shift inner bits
|
sh_next(N-1 downto 1) <= sh_reg(N-2 downto 0); -- shift inner bits
|
sh_next(0) <= rx_bit_next; -- shift in rx bit into LSb
|
sh_next(0) <= rx_bit_next; -- shift in rx bit into LSb
|
state_next <= state_reg - 1; -- update next state at each sck pulse
|
state_next <= state_reg - 1; -- update next state at each sck pulse
|
|
|
when 2 =>
|
when 2 => -- transfer received data to do_buffer_reg on next cycle
|
-- transfer parallel data on next state
|
|
di_req_next <= '1'; -- request data in advance to allow for pipeline delays
|
di_req_next <= '1'; -- request data in advance to allow for pipeline delays
|
wr_ack_next <= '0'; -- remove data load ack for all but the load stages
|
wr_ack_next <= '0'; -- remove data load ack for all but the load stages
|
tx_bit_next <= sh_reg(N-1); -- output next MSbit
|
tx_bit_next <= sh_reg(N-1); -- output next MSbit
|
sh_next(N-1 downto 1) <= sh_reg(N-2 downto 0); -- shift inner bits
|
sh_next(N-1 downto 1) <= sh_reg(N-2 downto 0); -- shift inner bits
|
sh_next(0) <= rx_bit_next; -- shift in rx bit into LSb
|
sh_next(0) <= rx_bit_next; -- shift in rx bit into LSb
|
do_transfer_next <= '1'; -- signal transfer to do_buffer on next cycle
|
do_transfer_next <= '1'; -- signal transfer to do_buffer on next cycle
|
do_buffer_next <= sh_next; -- get next data directly into rx buffer
|
do_buffer_next <= sh_next; -- get next data directly into rx buffer
|
state_next <= state_reg - 1; -- update next state at each sck pulse
|
state_next <= state_reg - 1; -- update next state at each sck pulse
|
|
|
when 1 =>
|
when 1 => -- transfer rx data to do_buffer and restart if new data is written
|
-- restart from state 'N' if more sck pulses come
|
|
sh_next(0) <= rx_bit_next; -- shift in rx bit into LSb
|
sh_next(0) <= rx_bit_next; -- shift in rx bit into LSb
|
sh_next(N-1 downto 1) <= di_reg(N-2 downto 0); -- shift inner bits
|
sh_next(N-1 downto 1) <= di_reg(N-2 downto 0); -- shift inner bits
|
tx_bit_next <= di_reg(N-1); -- first output bit comes from the MSb of parallel data
|
tx_bit_next <= di_reg(N-1); -- first output bit comes from the MSb of parallel data
|
di_req_next <= '0'; -- prefetch data request: deassert when shifting data
|
di_req_next <= '0'; -- prefetch data request: deassert when shifting data
|
if wren = '1' then -- load tx register if valid data present at di_reg
|
if wren = '1' then -- load tx register if valid data present at di_reg
|
Line 388... |
Line 384... |
wr_ack_next <= '0'; -- remove data load ack for all but the load stages
|
wr_ack_next <= '0'; -- remove data load ack for all but the load stages
|
sh_next <= (others => '0'); -- load null data (output '0' if no load)
|
sh_next <= (others => '0'); -- load null data (output '0' if no load)
|
state_next <= 0; -- next state is idle state
|
state_next <= 0; -- next state is idle state
|
end if;
|
end if;
|
|
|
when 0 =>
|
when 0 => -- idle state: start and end of transmission
|
sh_next(0) <= rx_bit_next; -- shift in rx bit into LSb
|
sh_next(0) <= rx_bit_next; -- shift in rx bit into LSb
|
sh_next(N-1 downto 1) <= di_reg(N-2 downto 0); -- shift inner bits
|
sh_next(N-1 downto 1) <= di_reg(N-2 downto 0); -- shift inner bits
|
wr_ack_next <= '1'; -- acknowledge data in transfer
|
wr_ack_next <= '1'; -- acknowledge data in transfer
|
di_req_next <= '0'; -- prefetch data request: deassert when shifting data
|
di_req_next <= '0'; -- prefetch data request: deassert when shifting data
|
do_transfer_next <= '0'; -- clear signal transfer to do_buffer
|
do_transfer_next <= '0'; -- clear signal transfer to do_buffer
|