Good morning all !!
I allow myself to turn to you today after several to seek the solutions
Indeed I am in a rather material project where it is necessary to set up
a dating device using a CPLD card.
One of the functions to perform is the description of an SPI. It is a
question of describing the SPI in such a way that we can have 4 states
at the output (00, 01, 10 and 11) and this according to two inputs which
are the CS and the CLOCK. For this, I use verilog as language.
The problem is that I cannot evaluate this condition "end else if
(CS_SPI == 1'b1 && i == 1'b0) begin
next_state = Trans_DataBit;
Count_Bit <= 4'b1100;
assign j = i;
in order to access the fourth state which would allow me to count down
the 12 bits of data to be transmitted.
I enclose the description and the timing diagram where I forced the
Thank you all in advance.
I have attached files for more details.
One of the problems is that you are changing >> Count_Bit << in two
separated always blocks, the simulator is kind of dead-locking.
Changing a register using blocking and non-blocking assignments is bad
because it doesn't synthesize : you have like "two drivers" for the same
signal, to put it simple.
always @(state or CS_SPI)
begin : MEF_SPI
next_state = 4'b0001;
//Count_DateBit <= 2'b11;
//Count_DataBit <= 4'b1111;
Trans_FlagBit : if(CS_SPI == 1'b1) begin
next_state = Trans_DateBit;
//i = 0;
//SPI_Select = 1;
Trans_DateBit : if(CS_SPI == 1'b1 && i!= 1'b0 ) begin
Thank you Von Ale for your answer.
I have fixed that problem but I still have some.
1 ) One of them is that I have a delay at the begining of the
SPI_Select. And that consequence of that delay is that the output is not
corresponding with the state anymore.
2 ) The other one is that I am not suppose to have 1111 after 0000 when
counting but I am having it and I don't really understang why.
I have attached the result of simulation and the description.
Count_Bit is still being modified in both always. Maybe you should do
one clocked always block for the state machine, instead of two.
You are using ModelSim to simulate, maybe you should try to synthesize
the code for some random FPGA, whatever you have installed, and have a
look at the errors and warnings you get. It helps with double written
registers and things like that :).
I also find that a state diagram with conditions helps during the design
phase and implementation phases, it helps you visualize what you intend
to do and to find possible misunderstandings between how you think the
problem can be solved and how you are trying to solve it :). Sometimes I
write down timing diagrams, helps too when the state machines get a bit
You are mixing two kinds of assignments '=' and '<=' they do not mean
the same and are to be used in different kinds of assignments !.
Short description: Inside a clocked always block use '<=' only.
What I see from the simulation is that SPI_Select is not being updated,
the simulator is not understanding your code correctly.
The use of an extra flag 'i' kinds of defeats the simplicity of the
state machine you have more unneeded states, when Count_Bit is zero you
this code is ...
Count_Bit <= Count_Bit -1;
The second one is the one that has effect, but which one was the
intended one ?
Verilog is not a procedural language, what you describe is hardware and
it works in parallel. So all assignments happen at the same time,
enables permitting, of course.
Count_Bit should be initialized before you transition to the next state,
in Trans_FlagBit and in Trans_DateBit before you go to Trans_DataBit
(when the bit counter is zero).
Jonas E. wrote:> in order to access the fourth state which would allow me to count down> the 12 bits of data to be transmitted.
Have a close look what SPI really is, then the world gets as simple as
it is: SPI are only two shift registers coupled one behind the other.
Is there any counter in this suprisingly description? No, because the
"easiest to handle" SPI slaves don't count any bits. Instead they simply
shift them out of or into a shift register while SS# is low. And they
handle new data while SS# is high.
Having brought this to mind, a implementation for a 24 bit parallel
in/out SPI device are only a few lines like those:
signaldsr:STD_LOGIC_VECTOR(breite-1downto0);-- the one and only SPI shift register
-- parallel inputs --> handle MISO
if(SS='1')then-- with "inactive" SS#: load parallel inputs
elsifrising_edge(SCLK)then-- with SS#=0 and each SCLK
dsr<=dsr(dsr'left-1downto0)&MOSI;-- shift left for new MISO and load MOSI as LSB
MISO<=dsr(dsr'left)whenSS='0'else'Z';-- map MSB of shift register to MISO
-- parallel outputs --> handle SS#
ifrising_edge(SS)then-- device is deselected at rising edge of SS#
Dout<=dsr;-- store shiftet data tparallel outputs
Its VHDL, but you will get the trick easily...
A SPI master is a little bit more tricky, and indeed some kind of
counter is necessary. But you must not (never ever!!)(**) use the SCLK
in a SPI master as a clock in your design. The one and only clock is the
50MHz (or whatsoever xtal is connected to your FPGA pins). All the other
"clocks" are simply synchronous signals.
See this VHDL implementation using exactly 1 clock:
(**) the only two groups of people using more than 1 clock in a FPGA
design are absolute beginners and absolute professionals. The ones
accidentally, the others with absolute caution.
Thank you once again,
I have tried to modified many of thing that you have mentioned but still
Is not evaluating even the first state because un the result the CS_SPI
is not working. Even the state and the Count_Bit are not working.
I don't realy know what I am missing.
I will be please to have your help again.
I have attached the description and the result.