First I would like to mention that I'm still new to the VHDL World so please bear with me.
Currently, I'm working on an SPI project where I created a generic master module that can send and receive different data widths ranging from 8 to 64 bits. Everything is working fine in my testbench regarding sending and receiving data between the master and the slave.
P.S. The master is synthesizable while the slave is just for simulation purposes.
In the testbench I instantiated many DUTs from the master and the slave, for instance, I created DUT_00 for testing 8bit data width, DUT_01 for 11bit data with, etc. As shown below:
Signal declaration for DUT_00 in my testbench
---------------------------------------------------------------------------------------------------------------------
-- DUT0 Signals
---------------------------------------------------------------------------------------------------------------------
constant data_width_8bit : positive range 8 to 64 := 8; --! data width from the master to the slave
--shared variable s_data_width : positive range 8 to 64 := data_width_00; --! data width from the master to the slave
constant bw_g : positive range 8 to 24 := 24; --! width of baud rate configuration port cbr_i
constant inv_g : natural range 0 to 1 := 0; --! 0: master and slave sample on same edge, 1: master samples on opposite edge as slave
signal clk_tb : std_logic:= '0'; --! system clock
signal rst_tb : std_logic:= '0'; --! system reset synchronous, high activsen_i
signal cbr_0tb :std_logic_vector(bw_g-1 downto 0):= x"00_0001"; --! clock baud rate configuration
signal cpol_0tb :std_logic:= '0'; --! clock polarity selection
signal cpha_0tb :std_logic :='0'; --! clock phase selection
signal sen_0tb :std_logic:='0'; --! slave enable : 1 => slave enabled, 0 => slave disabled
signal sts_0tb :std_logic:='0'; --! slave transfer start (unit pulse)
signal sbusy_0tb :std_logic; --! slave status: 1 => SPI transaction ongoing, 0 => idle
signal stv_0tb :std_logic; --! slave transfer valid (unit pulse)
signal dts_0tb :std_logic_vector(data_width_8bit-1 downto 0):= (others => '0'); --! parallel data to slave
signal dfs_0tb :std_logic_vector(data_width_8bit-1 downto 0); --! parallel data from slave
signal ss_0tb :std_logic; --! slave selection
signal spi_clk_0tb :std_logic; --! master clock
signal mosi_0tb :std_logic; --! serial data to slave (Master Output Slave Input)
signal miso_0tb :std_logic; --! serial data from slave (Master Input Slave Output)
---------------------------------------------------------------------------------------------------------------------
-- Slave Signals
---------------------------------------------------------------------------------------------------------------------
signal dfm_0tb :std_logic_vector(data_width_8bit-1 downto 0); --! parallel data from master
signal dfm_val_0tb :std_logic; --! valid pulse for data from master
signal dtm_0tb :std_logic_vector(data_width_8bit-1 downto 0):= (others => '0'); --! parallel data to master
signal busy_tx_0tb :std_logic; --! slave busy,Do not write data while high
signal dtm_val_0tb :std_logic; --! valid pulse for data to the master
signal sum_0tb :std_logic_vector(data_width_8bit-1 downto 0):= (others => '0'); --! bit counter for the data to the master
DUT_00 instantiation
DUT_Gen: for i in 0 to 4 generate
--! @brief instantiation of SPI master entity
DUT_00: if i = 0 generate
master_00: entity work.SPI_MASTER(rtl_SPI_MASTER)
generic map (
nb_g => data_width_8bit,
bw_g => bw_g,
inv_g => inv_g)
-- Master Ports Mapping
port map(
-------------------------------Master I/O pins------------------------------------------------------
clk_i => clk_tb,
rst_i => rst_tb,
-- HOST IF
cbr_i => cbr_0tb,
cpol_i => cpol_0tb,
cpha_i => cpha_0tb,
-- Control
sen_i => sen_0tb,
sts_i => sts_0tb,
sbusy_o => sbusy_0tb ,
stv_o => stv_0tb,
-- Data
dts_i => dts_0tb,
dfs_o => dfs_0tb,
-- SPI IF
spi_ss_o => ss_0tb,
spi_clk_o => spi_clk_0tb,
spi_mosi_o => mosi_0tb,
spi_miso_i=> miso_0tb );
slave_00: entity work.SPI_SLAVE(beh_SPI_SLAVE)
generic map (
nb_g => data_width_8bit
-- bw_g => bw_g
)
-- Slave Ports Mapping
port map(
-------------------------------Slave I/O pins------------------------------------------------------
clk_i => clk_tb,
rst_i => rst_tb,
cpol_i => cpol_0tb,
cpha_i => cpha_0tb,
sck_i => spi_clk_0tb,
mosi_i => mosi_0tb,
miso_o => miso_0tb,
cs_i => ss_0tb,
dfm_o => dfm_0tb,
dfm_val_o => dfm_val_0tb,
dtm_i => dtm_0tb,
busy_tx_o => busy_tx_0tb,
dtm_val_o => dtm_val_0tb,
sum_o => sum_0tb
-- sck_frq_o => sck_frq_0tb
);
end generate DUT_00;
DUT_01 instanstation
--! @brief instantiation of SPI master entity
DUT_01: if i = 1 generate
master_01: entity work.SPI_MASTER(rtl_SPI_MASTER)
generic map (
nb_g => data_width_11bit,
bw_g => bw_g,
inv_g => inv_g)
-- Master Ports Mapping
port map(
-------------------------------Master I/O pins------------------------------------------------------
clk_i => clk_tb,
rst_i => rst_tb,
-- HOST IF
cbr_i => cbr_1tb,
cpol_i => cpol_1tb,
cpha_i => cpha_1tb,
-- Control
sen_i => sen_1tb,
sts_i => sts_1tb,
sbusy_o => sbusy_1tb ,
stv_o => stv_1tb,
-- Data
dts_i => dts_1tb,
dfs_o => dfs_1tb,
-- SPI IF
spi_ss_o => ss_1tb,
spi_clk_o => spi_clk_1tb,
spi_mosi_o => mosi_1tb,
spi_miso_i=> miso_1tb );
slave_01: entity work.SPI_SLAVE(beh_SPI_SLAVE)
generic map (
nb_g => data_width_11bit
-- bw_g => bw_g
)
-- Slave Ports Mapping
port map(
-------------------------------Slave I/O pins------------------------------------------------------
clk_i => clk_tb,
rst_i => rst_tb,
cpol_i => cpol_1tb,
cpha_i => cpha_1tb,
sck_i => spi_clk_1tb,
mosi_i => mosi_1tb,
miso_o => miso_1tb,
cs_i => ss_1tb,
dfm_o => dfm_1tb,
dfm_val_o => dfm_val_1tb,
dtm_i => dtm_1tb,
busy_tx_o => busy_tx_1tb,
dtm_val_o => dtm_val_1tb,
sum_o => sum_1tb
-- sck_frq_o => sck_frq_1tb
);
end generate DUT_01;
My first question is, instead of creating many DUTs for every different data width, how can I only use one DUT that can handle different data sizes also different baud rates?
Second, how can I make the slave detect the mode that has been used by the master when it sends data without telling the slave explicitly which Phase and polarity have been used?
Sorry if my question wasn't well-stated at the beginning.