URL
https://opencores.org/ocsvn/spi_master_slave/spi_master_slave/trunk
Subversion Repositories spi_master_slave
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 11 to Rev 10
- ↔ Reverse comparison
Rev 11 → Rev 10
/spi_master_slave/trunk/rtl/spi_master.vhd
134,10 → 134,6
-- 2011/07/10 v1.10.0075 [JD] verified spi_master_slave in silicon at 50MHz, 25MHz, 16.666MHz, 12.5MHz, 10MHz, 8.333MHz, |
-- 7.1428MHz, 6.25MHz, 1MHz and 500kHz. The core proved very robust at all tested frequencies. |
-- 2011/07/16 v1.11.0080 [JD] verified both spi_master and spi_slave in loopback at 50MHz SPI clock. |
-- 2011/07/17 v1.11.0080 [JD] BUG: CPOL='1', CPHA='1' @50MHz causes MOSI to be shifted one bit earlier. |
-- BUG: CPOL='0', CPHA='1' causes SCK to have one extra pulse with one sclk_i width at the end. |
-- 2011/07/18 v1.12.0105 [JD] CHG: spi sck output register changed to remove glitch at last clock when CPHA='1'. |
-- for CPHA='1', max spi clock is 25MHz. for CPHA= '0', max spi clock is >50MHz. |
-- |
----------------------------------------------------------------------------------------------------------------------- |
-- TODO |
201,18 → 197,17
--================================================================================================================ |
architecture RTL of spi_master is |
-- core clocks, generated from 'sclk_i': initialized to differential values |
signal core_clk : std_logic := '0'; -- continuous core clock, positive logic |
signal core_n_clk : std_logic := '1'; -- continuous core clock, negative logic |
signal core_ce : std_logic := '0'; -- core clock enable, positive logic |
signal core_n_ce : std_logic := '1'; -- core clock enable, negative logic |
signal core_clk : std_logic := '0'; -- continuous core clock, positive logic |
signal core_n_clk : std_logic := '1'; -- continuous core clock, negative logic |
signal core_ce : std_logic := '0'; -- core clock enable, positive logic |
signal core_n_ce : std_logic := '1'; -- core clock enable, negative logic |
-- spi bus clock, generated from the CPOL selected core clock polarity |
signal spi_2x_ce : std_logic := '1'; -- spi_2x clock enable |
signal spi_clk : std_logic := '0'; -- spi bus output clock |
signal spi_clk_reg : std_logic := '0'; -- output pipeline delay for spi sck |
signal spi_2x_ce : std_logic := '1'; -- spi_2x clock enable |
signal spi_clk : std_logic := '0'; -- spi bus output clock |
signal spi_clk_reg : std_logic := '0'; -- output pipeline delay for spi sck |
-- core fsm clock enables |
signal fsm_ce : std_logic := '1'; -- fsm clock enable |
signal ena_sck_ce : std_logic := '1'; -- SCK clock enable |
signal samp_ce : std_logic := '1'; -- data sampling clock enable |
signal fsm_ce : std_logic := '1'; -- fsm clock enable |
signal samp_ce : std_logic := '1'; -- data sampling clock enable |
-- |
-- GLOBAL RESET: |
-- all signals are initialized to zero at GSR (global set/reset) by giving explicit |
338,12 → 333,12
end process core_clock_gen_proc; |
----------------------------------------------------------------------------------------------- |
-- spi clk generator: generate spi_clk from core_clk depending on CPOL |
spi_sck_cpol_0_proc : |
spi_sck_cpol_0_proc : |
if CPOL = '0' generate |
begin |
spi_clk <= core_clk; -- for CPOL=0, spi clk has idle LOW |
end generate; |
spi_sck_cpol_1_proc : |
spi_sck_cpol_1_proc : |
if CPOL = '1' generate |
begin |
spi_clk <= core_n_clk; -- for CPOL=1, spi clk has idle HIGH |
351,12 → 346,12
----------------------------------------------------------------------------------------------- |
-- Sampling clock enable generation: generate 'samp_ce' from 'core_ce' or 'core_n_ce' depending on CPHA |
-- always sample data at the half-cycle of the fsm update cell |
samp_ce_cpha_0_proc : |
samp_ce_cpha_0_proc : |
if CPHA = '0' generate |
begin |
samp_ce <= core_ce; |
end generate; |
samp_ce_cpha_1_proc : |
samp_ce_cpha_1_proc : |
if CPHA = '1' generate |
begin |
samp_ce <= core_n_ce; |
363,19 → 358,17
end generate; |
----------------------------------------------------------------------------------------------- |
-- FSM clock enable generation: generate 'fsm_ce' from core_ce or core_n_ce depending on CPHA |
fsm_ce_cpha_0_proc : |
fsm_ce_cpha_0_proc : |
if CPHA = '0' generate |
begin |
fsm_ce <= core_n_ce; -- for CPHA=0, latch registers at rising edge of negative core clock enable |
end generate; |
fsm_ce_cpha_1_proc : |
fsm_ce_cpha_1_proc : |
if CPHA = '1' generate |
begin |
fsm_ce <= core_ce; -- for CPHA=1, latch registers at rising edge of positive core clock enable |
end generate; |
|
ena_sck_ce <= core_n_ce; -- for CPHA=1, SCK is advanced one-half cycle |
|
--============================================================================================= |
-- REGISTERED INPUTS |
--============================================================================================= |
386,11 → 379,11
-- |
rx_bit_proc : process (sclk_i, spi_miso_i) is |
begin |
if sclk_i'event and sclk_i = '1' then |
if samp_ce = '1' then |
-- if sclk_i'event and sclk_i = '1' then |
-- if samp_ce = '1' then |
rx_bit_reg <= spi_miso_i; |
end if; |
end if; |
-- end if; |
-- end if; |
end process rx_bit_proc; |
|
--============================================================================================= |
455,7 → 448,7
state_reg <= state_next; -- state register |
end if; |
end if; |
-- FF registers clocked synchronous to the fsm state |
-- FF registers clocked on rising edge |
if sclk_i'event and sclk_i = '1' then |
if fsm_ce = '1' then |
sh_reg <= sh_next; -- shift register |
467,12 → 460,6
wren_ack_reg <= wren_ack_next; -- wren ack for data load synchronization |
end if; |
end if; |
-- FF registers clocked one-half cycle earlier than the fsm state |
-- if sclk_i'event and sclk_i = '1' then |
-- if ena_sck_ce = '1' then |
-- ena_sck_reg <= ena_sck_next; -- spi clock enable |
-- end if; |
-- end if; |
end process core_reg_proc; |
|
--============================================================================================= |
552,19 → 539,12
-- enabling higher SCK frequency. The MOSI and SCK phase are compensated by the pipeline delay. |
spi_sck_o_gen_proc : process (sclk_i, ena_sck_reg, spi_clk, spi_clk_reg) is |
begin |
-- if sclk_i'event and sclk_i = '1' then |
-- if ena_sck_reg = '1' then |
-- spi_clk_reg <= spi_clk; -- copy the selected clock polarity |
-- else |
-- spi_clk_reg <= CPOL; -- when clock disabled, set to idle polarity |
-- end if; |
-- end if; |
if ena_sck_reg = '1' then |
if sclk_i'event and sclk_i = '1' then |
if sclk_i'event and sclk_i = '1' then |
if ena_sck_reg = '1' then |
spi_clk_reg <= spi_clk; -- copy the selected clock polarity |
else |
spi_clk_reg <= CPOL; -- when clock disabled, set to idle polarity |
end if; |
else |
spi_clk_reg <= CPOL; -- when clock disabled, set to idle polarity |
end if; |
spi_sck_o <= spi_clk_reg; -- connect register to output |
end process spi_sck_o_gen_proc; |
/spi_master_slave/trunk/syn/spi_master_atlys_top_bit.zip
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/spi_master_slave/trunk/syn/spi_master_atlys_top.vhd
15,6 → 15,8
-- The test circuit uses the VHDCI connector on the Atlys to implement a 16-pin debug port to be used |
-- with a Tektronix MSO2014. The 16 debug pins are brought to 2 8x2 headers that form a umbilical |
-- digital pod port. |
-- The board switches are used to set the SPI_MASTER transmit data, and the SPI_SLAVE receive data drives the switch LEDs. |
-- The pushbuttons drive the slave transmit data, and the master received data drives the parallel debug port. |
-- |
------------------------------ REVISION HISTORY ----------------------------------------------------------------------- |
-- |
27,17 → 29,17
-- external monitoring pins to the VHDCI ports. |
-- 2011/07/10 v1.10.0075 [JD] verified spi_master_slave at 50MHz, 25MHz, 16.666MHz, 12.5MHz, 10MHz, 8.333MHz, 7.1428MHz, |
-- 6.25MHz, 1MHz and 500kHz |
-- 2011/07/18 v1.12.0105 [JD] spi_master.vhd changed to fix CPHA='1' clock glitch. |
-- |
-- |
---------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_arith.all; |
use ieee.std_logic_arith.all; |
|
entity spi_master_atlys_top is |
Port ( |
gclk_i : in std_logic := 'X'; -- board clock input 100MHz |
clear_i : in std_logic := '0'; -- btn used as clear signal |
--- SPI interface --- |
spi_ssel_o : out std_logic; -- spi port SSEL |
spi_sck_o : out std_logic; -- spi port SCK |
55,9 → 57,9
spi_rx_bit_m_o : out std_logic; -- master rx bit feedback |
spi_rx_bit_s_o : out std_logic; -- slave rx bit feedback |
spi_do_valid_o : out std_logic; -- spi data valid |
spi_di_req_o : out std_logic -- spi data request |
-- spi_wren_o : out std_logic; -- spi write enable |
-- spi_wren_ack_o : out std_logic -- spi write enable ack |
spi_di_req_o : out std_logic; -- spi data request |
spi_wren_o : out std_logic; -- spi write enable |
spi_wren_ack_o : out std_logic -- spi write enable ack |
); |
end spi_master_atlys_top; |
|
72,9 → 74,7
constant SPI_2X_CLK_DIV : integer := 1; -- 50MHz SPI clock |
constant SAMP_CE_DIV : integer := 1; -- board signals sampled at 100MHz |
-- spi port generics |
constant N : integer := 8; -- 8 bits |
constant CPOL : std_logic := '0'; |
constant CPHA : std_logic := '0'; |
constant N : integer := 8; -- 8 bits |
|
-- button definitions |
constant btRESET : integer := 0; -- these are constants to use as btn_i(x) |
88,7 → 88,7
-- Type definitions |
--============================================================================================= |
type fsm_state_type is (st_reset, st_wait_spi_idle, st_wait_new_switch, |
st_send_spi_data, st_wait_spi_ack, st_wait_spi_finish ); |
st_send_spi_data, st_wait_spi_ack, st_wait_spi_finish ); |
|
--============================================================================================= |
-- Signals for state machine control |
161,7 → 161,7
-- receives parallel data from the slide switches, transmits to slave port. |
-- receives serial data from slave port, sends to 8bit parallel debug port. |
Inst_spi_master_port: entity work.spi_master(rtl) |
generic map (N => N, CPOL => CPOL, CPHA => CPHA, PREFETCH => 3, SPI_2X_CLK_DIV => SPI_2X_CLK_DIV) |
generic map (N => N, CPOL => '0', CPHA => '0', PREFETCH => 3, SPI_2X_CLK_DIV => SPI_2X_CLK_DIV) |
port map( |
sclk_i => gclk_i, -- system clock is used for serial and parallel ports |
pclk_i => gclk_i, |
176,7 → 176,7
do_o => spi_do_m, |
rx_bit_reg_o => spi_rx_bit_m, |
wren_i => spi_wren_reg_m, |
-- wren_o => spi_wren_o, |
wren_o => spi_wren_o, |
wren_ack_o => spi_wr_ack_m -- monitor wren ack from inside spi port |
); |
|
187,7 → 187,7
-- receives parallel data from the pushbuttons, transmits to master port. |
-- receives serial data from master port, sends to the 8 LEDs. |
Inst_spi_slave_port: entity work.spi_slave(rtl) |
generic map (N => N, CPOL => CPOL, CPHA => CPHA, PREFETCH => 3) |
generic map (N => N, CPOL => '0', CPHA => '0', PREFETCH => 3) |
port map( |
clk_i => gclk_i, |
spi_ssel_i => spi_ssel, -- generated by the spi master |
202,12 → 202,10
do_o => spi_do_s |
); |
|
spi_di_reg_s(7) <= btn_data(btLEFT); -- get the slave transmit data from pushbuttons |
spi_di_reg_s(6) <= btn_data(btCENTER); |
spi_di_reg_s(5 downto 1) <= B"10101"; |
spi_di_reg_s(0) <= btn_data(btRIGHT); |
spi_wren_reg_s <= '1'; -- fix wren to '1', for continuous load of transmit data |
spi_rx_bit_s_o <= spi_rx_bit_s; -- connect rx_bit monitor for slave port |
spi_di_reg_s(7 downto 5) <= B"101"; -- get the slave transmit data from pushbuttons |
spi_di_reg_s(4 downto 0) <= btn_data(5 downto 1); |
spi_wren_reg_s <= '1'; -- fix wren to '1', for continuous load of transmit data |
spi_rx_bit_s_o <= spi_rx_bit_s; -- connect rx_bit monitor for slave port |
|
-- debounce for the input switches, with new data strobe output |
Inst_sw_debouncer: entity work.grp_debouncer(rtl) |
233,16 → 231,16
-- CONSTANTS CONSTRAINTS CHECKING |
--============================================================================================= |
-- clock dividers shall not be zero |
assert FSM_CE_DIV > 0 |
report "Constant 'FSM_CE_DIV' should not be zero" |
assert FSM_CE_DIV > 0 |
report "Constant 'FSM_CE_DIV' should not be zero" |
severity FAILURE; |
-- minimum prefetch lookahead check |
assert SPI_2X_CLK_DIV > 0 |
report "Constant 'SPI_2X_CLK_DIV' should not be zero" |
assert SPI_2X_CLK_DIV > 0 |
report "Constant 'SPI_2X_CLK_DIV' should not be zero" |
severity FAILURE; |
-- maximum prefetch lookahead check |
assert SAMP_CE_DIV > 0 |
report "Constant 'SAMP_CE_DIV' should not be zero" |
assert SAMP_CE_DIV > 0 |
report "Constant 'SAMP_CE_DIV' should not be zero" |
severity FAILURE; |
|
--============================================================================================= |
406,7 → 404,7
spi_miso_o_proc: spi_miso_o <= spi_miso; |
spi_do_valid_o_proc: spi_do_valid_o <= spi_do_valid_m; |
spi_di_req_o_proc: spi_di_req_o <= spi_di_req_m; |
-- spi_wren_ack_o_proc: spi_wren_ack_o <= spi_wr_ack_m; |
spi_wren_ack_o_proc: spi_wren_ack_o <= spi_wr_ack_m; |
led_o_proc: led_o <= leds_reg; -- connect leds_reg signal to LED outputs |
|
--============================================================================================= |
/spi_master_slave/trunk/syn/spi_master.vhd
134,10 → 134,6
-- 2011/07/10 v1.10.0075 [JD] verified spi_master_slave in silicon at 50MHz, 25MHz, 16.666MHz, 12.5MHz, 10MHz, 8.333MHz, |
-- 7.1428MHz, 6.25MHz, 1MHz and 500kHz. The core proved very robust at all tested frequencies. |
-- 2011/07/16 v1.11.0080 [JD] verified both spi_master and spi_slave in loopback at 50MHz SPI clock. |
-- 2011/07/17 v1.11.0080 [JD] BUG: CPOL='1', CPHA='1' @50MHz causes MOSI to be shifted one bit earlier. |
-- BUG: CPOL='0', CPHA='1' causes SCK to have one extra pulse with one sclk_i width at the end. |
-- 2011/07/18 v1.12.0105 [JD] CHG: spi sck output register changed to remove glitch at last clock when CPHA='1'. |
-- for CPHA='1', max spi clock is 25MHz. for CPHA= '0', max spi clock is >50MHz. |
-- |
----------------------------------------------------------------------------------------------------------------------- |
-- TODO |
201,18 → 197,17
--================================================================================================================ |
architecture RTL of spi_master is |
-- core clocks, generated from 'sclk_i': initialized to differential values |
signal core_clk : std_logic := '0'; -- continuous core clock, positive logic |
signal core_n_clk : std_logic := '1'; -- continuous core clock, negative logic |
signal core_ce : std_logic := '0'; -- core clock enable, positive logic |
signal core_n_ce : std_logic := '1'; -- core clock enable, negative logic |
signal core_clk : std_logic := '0'; -- continuous core clock, positive logic |
signal core_n_clk : std_logic := '1'; -- continuous core clock, negative logic |
signal core_ce : std_logic := '0'; -- core clock enable, positive logic |
signal core_n_ce : std_logic := '1'; -- core clock enable, negative logic |
-- spi bus clock, generated from the CPOL selected core clock polarity |
signal spi_2x_ce : std_logic := '1'; -- spi_2x clock enable |
signal spi_clk : std_logic := '0'; -- spi bus output clock |
signal spi_clk_reg : std_logic := '0'; -- output pipeline delay for spi sck |
signal spi_2x_ce : std_logic := '1'; -- spi_2x clock enable |
signal spi_clk : std_logic := '0'; -- spi bus output clock |
signal spi_clk_reg : std_logic := '0'; -- output pipeline delay for spi sck |
-- core fsm clock enables |
signal fsm_ce : std_logic := '1'; -- fsm clock enable |
signal ena_sck_ce : std_logic := '1'; -- SCK clock enable |
signal samp_ce : std_logic := '1'; -- data sampling clock enable |
signal fsm_ce : std_logic := '1'; -- fsm clock enable |
signal samp_ce : std_logic := '1'; -- data sampling clock enable |
-- |
-- GLOBAL RESET: |
-- all signals are initialized to zero at GSR (global set/reset) by giving explicit |
338,12 → 333,12
end process core_clock_gen_proc; |
----------------------------------------------------------------------------------------------- |
-- spi clk generator: generate spi_clk from core_clk depending on CPOL |
spi_sck_cpol_0_proc : |
spi_sck_cpol_0_proc : |
if CPOL = '0' generate |
begin |
spi_clk <= core_clk; -- for CPOL=0, spi clk has idle LOW |
end generate; |
spi_sck_cpol_1_proc : |
spi_sck_cpol_1_proc : |
if CPOL = '1' generate |
begin |
spi_clk <= core_n_clk; -- for CPOL=1, spi clk has idle HIGH |
351,12 → 346,12
----------------------------------------------------------------------------------------------- |
-- Sampling clock enable generation: generate 'samp_ce' from 'core_ce' or 'core_n_ce' depending on CPHA |
-- always sample data at the half-cycle of the fsm update cell |
samp_ce_cpha_0_proc : |
samp_ce_cpha_0_proc : |
if CPHA = '0' generate |
begin |
samp_ce <= core_ce; |
end generate; |
samp_ce_cpha_1_proc : |
samp_ce_cpha_1_proc : |
if CPHA = '1' generate |
begin |
samp_ce <= core_n_ce; |
363,19 → 358,17
end generate; |
----------------------------------------------------------------------------------------------- |
-- FSM clock enable generation: generate 'fsm_ce' from core_ce or core_n_ce depending on CPHA |
fsm_ce_cpha_0_proc : |
fsm_ce_cpha_0_proc : |
if CPHA = '0' generate |
begin |
fsm_ce <= core_n_ce; -- for CPHA=0, latch registers at rising edge of negative core clock enable |
end generate; |
fsm_ce_cpha_1_proc : |
fsm_ce_cpha_1_proc : |
if CPHA = '1' generate |
begin |
fsm_ce <= core_ce; -- for CPHA=1, latch registers at rising edge of positive core clock enable |
end generate; |
|
ena_sck_ce <= core_n_ce; -- for CPHA=1, SCK is advanced one-half cycle |
|
--============================================================================================= |
-- REGISTERED INPUTS |
--============================================================================================= |
386,11 → 379,11
-- |
rx_bit_proc : process (sclk_i, spi_miso_i) is |
begin |
if sclk_i'event and sclk_i = '1' then |
if samp_ce = '1' then |
-- if sclk_i'event and sclk_i = '1' then |
-- if samp_ce = '1' then |
rx_bit_reg <= spi_miso_i; |
end if; |
end if; |
-- end if; |
-- end if; |
end process rx_bit_proc; |
|
--============================================================================================= |
455,7 → 448,7
state_reg <= state_next; -- state register |
end if; |
end if; |
-- FF registers clocked synchronous to the fsm state |
-- FF registers clocked on rising edge |
if sclk_i'event and sclk_i = '1' then |
if fsm_ce = '1' then |
sh_reg <= sh_next; -- shift register |
467,12 → 460,6
wren_ack_reg <= wren_ack_next; -- wren ack for data load synchronization |
end if; |
end if; |
-- FF registers clocked one-half cycle earlier than the fsm state |
-- if sclk_i'event and sclk_i = '1' then |
-- if ena_sck_ce = '1' then |
-- ena_sck_reg <= ena_sck_next; -- spi clock enable |
-- end if; |
-- end if; |
end process core_reg_proc; |
|
--============================================================================================= |
552,19 → 539,12
-- enabling higher SCK frequency. The MOSI and SCK phase are compensated by the pipeline delay. |
spi_sck_o_gen_proc : process (sclk_i, ena_sck_reg, spi_clk, spi_clk_reg) is |
begin |
-- if sclk_i'event and sclk_i = '1' then |
-- if ena_sck_reg = '1' then |
-- spi_clk_reg <= spi_clk; -- copy the selected clock polarity |
-- else |
-- spi_clk_reg <= CPOL; -- when clock disabled, set to idle polarity |
-- end if; |
-- end if; |
if ena_sck_reg = '1' then |
if sclk_i'event and sclk_i = '1' then |
if sclk_i'event and sclk_i = '1' then |
if ena_sck_reg = '1' then |
spi_clk_reg <= spi_clk; -- copy the selected clock polarity |
else |
spi_clk_reg <= CPOL; -- when clock disabled, set to idle polarity |
end if; |
else |
spi_clk_reg <= CPOL; -- when clock disabled, set to idle polarity |
end if; |
spi_sck_o <= spi_clk_reg; -- connect register to output |
end process spi_sck_o_gen_proc; |
/spi_master_slave/trunk/syn/spi_master_scope_photos.zip
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/spi_master_slave/trunk/syn/spi_master_envsettings.html
386,12 → 386,6
<td><b>Default Value</b></td> |
</tr> |
<tr> |
<td>-detail</td> |
<td>Generate Detailed MAP Report</td> |
<td>TRUE</td> |
<td>TRUE</td> |
</tr> |
<tr> |
<td>-ol</td> |
<td>Place & Route Effort Level (Overall)</td> |
<td>high</td> |