Good morning all !!
I allow myself to turn to you today after several to seek the solutions
without success.
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;
end
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
entries.
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.
1
always @(state or CS_SPI)
2
begin : MEF_SPI
3
next_state = 4'b0001;
4
5
6
//Count_Bit <=4'b0011;
7
//Count_DateBit <= 2'b11;
8
//Count_DataBit <= 4'b1111;
9
10
case(state)
11
...
12
Trans_FlagBit : if(CS_SPI == 1'b1) begin
13
next_state = Trans_DateBit;
14
Count_Bit =4'b0011;
15
//i = 0;
16
//i=3;
17
//SPI_Select = 1;
18
end
19
20
21
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
too complicated.
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
can transition.
this code is ...
1
Count_Bit <=4'b1011;
2
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).
A nice example of a SPI controller is given in the site fpga4fun, They
explain the workings too, you may give it a look. The good thing is that
they examples while simple, actually work !
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:
1
libraryIEEE;
2
useIEEE.STD_LOGIC_1164.ALL;
3
useIEEE.NUMERIC_STD.ALL;
4
5
entitySPI_Slaveis
6
Generic(breite:natural:=24);
7
Port(SCLK:inSTD_LOGIC;
8
SS:inSTD_LOGIC;
9
MOSI:inSTD_LOGIC;
10
MISO:outSTD_LOGIC;
11
Dout:outSTD_LOGIC_VECTOR(breite-1downto0);
12
Din:inSTD_LOGIC_VECTOR(breite-1downto0));
13
endSPI_Slave;
14
15
architectureBehavioralofSPI_Slaveis
16
17
signaldsr:STD_LOGIC_VECTOR(breite-1downto0);-- the one and only SPI shift register
18
19
begin
20
21
-- parallel inputs --> handle MISO
22
process(SS,Din,SCLK)begin
23
if(SS='1')then-- with "inactive" SS#: load parallel inputs
24
dsr<=Din;
25
elsifrising_edge(SCLK)then-- with SS#=0 and each SCLK
26
dsr<=dsr(dsr'left-1downto0)&MOSI;-- shift left for new MISO and load MOSI as LSB
27
endif;
28
endprocess;
29
MISO<=dsr(dsr'left)whenSS='0'else'Z';-- map MSB of shift register to MISO
30
31
-- parallel outputs --> handle SS#
32
process(SS)begin
33
ifrising_edge(SS)then-- device is deselected at rising edge of SS#
34
Dout<=dsr;-- store shiftet data tparallel outputs
35
endif;
36
endprocess;
37
38
endBehavioral;
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:
http://www.lothar-miller.de/s9y/categories/45-SPI-Master
(**) 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
don't work.
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.