06-15-2009 11:47 AM
I am trying to design a SPI communication block. I want the input/output signal and buffers to be zero on reset. But I am having problems since 2 processes operate on the same signal.
Now I am not sure how to use a global reset. should it be outside a process?
Reset is synchronous. The first process - process(clk) resets all I/Os when the Reset is LOW.
Another process - process(sclk) takes care of serial data transfer.
When I simulate, sin_data and sout_data are 'unknown'. I don't understand the reason why they are unknown.
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; ---- Uncomment the following library declaration if instantiating ---- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all; entity myspi is PORT ( clk: in std_logic; --FPGA clock rst : in std_logic; -- Reset input active low ss : inout std_logic; -- slave select input, active low sclk: inout std_logic; -- clock for SPI interface sout: out std_logic; -- serial data out bit sin: in std_logic); -- serial data in from MAX or other SPI device end myspi; architecture Behavioral of myspi is --sin_data and sout_data are like input and output data buffers --sin and sout are the like input and output ports (SDI, SDO to be exact) signal sout_data : std_logic_vector(7 downto 0):="11101010"; --this is where serial data byte is stored and transfered bit by bit signal sin_data : std_logic_vector (7 downto 0); --input byte from serial data in signal ser_clk : std_logic; --created to use in process since sclk is output and hence cannot be used in a process signal sclk_gate : std_logic; --this is used to gate sclk. sclk will have 8 pulses then goes high for 2 sclk period and then back to 8 pulses Begin process(clk) variable n,m: integer:=0; Begin --Normal operation if reset is high If (clk'Event and clk='1') then --generate 2.5MHz clock for SPI If (rst ='0') then --If RESET is active, then make all I/Os LOW/HIGH ser_clk<='0'; sclk_gate<='0'; ss<='1'; --No slaves should be selected sin_data<="00000000"; --Make the input and output buffers zero sout_data<="00000000"; elsif (rst='1') then n:=n+1; If(n= 10) then --(assumed 50MHz FPGA clk) ser_clk<=not(ser_clk); n:=0; m:=m+1; sclk_gate<='1'; If (m>16) then sclk_gate<='0'; end if; if (m=21) then m:=0; end if; end if; end if; end if; end process; Process(ser_clk) --sclk generation is done in a seperate process as sclk gate and ser clk are not update until the end of process(clk) begin sclk<=ser_clk AND sclk_gate; end process; Process(sclk) variable p : integer:= 7; Variable q : integer:= 0; Begin If (sclk'event and sclk='1') then --if sclk is high start sending data on rising edge p:=p-1; if ( p >0) then --if clk is less than 8 pulses then transmitting data, else stop data sout<=sout_data(p); --msbit first else p:=7; end if; elsif (sclk'event and sclk='0') then -- if sclk is falling edge then read data - 8 bits at a time if (q<8) then sin_data(q)<=sin; --In SPI MS bit is transmitted first, so store appropriately q:=q+1; else q:=0; end if; end if; end process; end Behavioral;
Solved! Go to Solution.
06-15-2009 11:59 PM
with unknown you mean 'X'es in your simulation?
Well look at this:
You did almost the same. Not in your testbench, but in your design.
A process becomes a piece of hardware.
When you have two processes assignig values to the same signal it's like soldering the outputs of two ICs together.
The result is hot, smelly and fuming.
Luckily your simulator detects this condition and shouts in japanese "Dame yo!" = "X"
When you synthesize it there should also come awarning or an error complaining about multiple drivers.
So, dont do it.
And when your signal is only driven by just one process, you also have no problem with the reset anymore.
Have a nice simulation