"rising_edge(clk)" and delay

K

kristoff

Guest
Hi,


I know this is very much a beginners question but I did try to find the
answer online and at a couple of books but have not yet found an clear
answer.


I'll ask the question based on a practicle example: in a process, I need
to to things at two different rates: certain things at the full clock
rate and a slower clock.


I have a basic clock 12 Mhz clock, so I build a clock-divider.


But, as I know I will need that slower clock in multiple places, my idea
would be to have a seperate process for creating the 1 Khz clock and
feed that into the processes that need that.


My code is below.


I have two questions from a generic "how to design a syncrounous system"
one.

1/ Is this the right way to do this?

Does it make sence to create one clock-divider as a seperate process and
feed then then into other process? (so not to have to synthesiser to
create one per every process that needs one).

Or can I just code the clock-divider into every process that needs that.
(Perhaps the synthesier will optimise the design anyway and do all the
work for me).


2/ From a timing point of view, the div12000-clock output of the clock
divider sits after some logic and is then feed into the other processes.
I guess this will create some delay.

But in the processes that actually use that clock (processes "a" and "b"
in my example) , the vhdl code to check on that signal sits behind a
"rising_edge(clk_in)", which is -if I am correct- a very short timespan.

Will this not result in timing-issues?
Can I be sure that the "slowclock = 1" will arrive in process "a" and
"b" fast enough.

Or will the synthesiser do special things to make sure it will. (perhaps
delay clk_in in the processes "a" and "b" a little bit).



Or, in a more generic sence,

When doing an initial design of a syncrounous system, do you need to
take timing-issues like this in account?

Or can I just assume there is zero-delay in all processes and let
timing-issues be dealt with by the synthesizer?

(I did read some comments that it will at least check certain elements
concerning timing of the design).



I did a very interesting post in a forum that clock-signals in a FPGA
are special and that clock-signals pass over special "lanes" (or
whatever the correct term is) so they arrive at all places in the chip
at the same moment.


It would however be interesting to find some information on how to deal
with clock-signals (especially if you create them yourself in a
clock-divider) in a syncronous design.




--- cut here --- cut here --- cut here ---

clockdiv12000: process (clk_in) is
begin
if (rising_edge(clk_in) then
if (counter = 11999) then
counter <= 0;
slowclock <= '1';
else
counter <= counter + 1;
slowclock <= '0';
end if;
end if; -- end rising_edge
end process clockdiv8000;


a: process (clk_in, slowclock, in1, in2) is
begin

if (rising_edge(clk_in) then

(do some stuff at 8 Mhz clock)

if (slowclock = '1') then
(do some stuff at 1 Khz clock)
end if;
end if;

end process a;


b: process (clk_in, slowclock, in3, in4) is
begin

if (rising_edge(clk_in) then

(do some stuff at 8 Mhz clock)

if (slowclock = '1') then
(do some stuff at 1 Khz clock)
end if;
end if;

end process b;

--- cut here --- cut here --- cut here ---



Cheerio! Kr. Bonne.
 
On Friday, June 10, 2016 at 2:53:55 AM UTC-4, kristoff wrote:
I have two questions from a generic "how to design a syncrounous system"
one.

1/ Is this the right way to do this?

If your target is an ASIC, then the answer might be yes. Otherwise, the answer is no. The way to do it is to create clock enable signals and then use them to enable the processes like this
process(My_high_speed_clock)
begin
if rising_edge(My_high_speed_clock)
if (Clock_Enable_1KHz = '1') then
...put your stuff that would be clocked by 1kHz here
end if;
end if;
end process;

Does it make sence to create one clock-divider as a seperate process and
feed then then into other process? (so not to have to synthesiser to
create one per every process that needs one).

The synthesizer wouldn't do what you describe, it would create only one instance.

Or can I just code the clock-divider into every process that needs that.
(Perhaps the synthesier will optimise the design anyway and do all the
work for me).

From a code maintenance standpoint, it would be better to create the divider once and use it everywhere. Again, the divider would be generating a clock enable signal to use, not an actual clock signal.

2/ From a timing point of view, the div12000-clock output of the clock
divider sits after some logic and is then feed into the other processes.
I guess this will create some delay.

Again, if targeting an ASIC, the answer might be yes. Otherwise, the answer is no. You will be creating timing problems that you can't actually fix, only get lucky at best to get it to sometimes work.

But in the processes that actually use that clock (processes "a" and "b"
in my example) , the vhdl code to check on that signal sits behind a
"rising_edge(clk_in)", which is -if I am correct- a very short timespan.

Will this not result in timing-issues?

Yes

Can I be sure that the "slowclock = 1" will arrive in process "a" and
"b" fast enough.

Or will the synthesiser do special things to make sure it will. (perhaps
delay clk_in in the processes "a" and "b" a little bit).

Synthesis implements what you describe even when you describe something that has an inherent design flaw.

Or, in a more generic sence,

When doing an initial design of a syncrounous system, do you need to
take timing-issues like this in account?

Consider clocking and timing upfront on every design.

Or can I just assume there is zero-delay in all processes and let
timing-issues be dealt with by the synthesizer?

Only if you want to spend time trying to debug why your design works for a couple of minutes and then stops for some reason.

I did a very interesting post in a forum that clock-signals in a FPGA
are special and that clock-signals pass over special "lanes" (or
whatever the correct term is) so they arrive at all places in the chip
at the same moment.

Not exactly the same time, but they arrive quickly enough that they guarantee that no matter which flip flops get connected, the clock will get there first.

It would however be interesting to find some information on how to deal
with clock-signals (especially if you create them yourself in a
clock-divider) in a syncronous design.

Synchronous designs use a single clock, not multiple. If something needs to happen periodically at a lower rate, you generate a clock enable signal using a counter. For example, if you have a 50 MHz clock but would like to generate a 1 MHz 'clock', what you would do is create a counter that counts from 0 to 49 and then resets back to 0. The clock enable signal would be active whenever the counter is a particular value (say 0 or 49 for example).. That generates a one clock cycle wide pulse that then gets used as I outlined earlier.

Kevin Jennings
 
On 6/10/2016 2:53 AM, kristoff wrote:
Hi,


I know this is very much a beginners question but I did try to find the
answer online and at a couple of books but have not yet found an clear
answer.


I'll ask the question based on a practicle example: in a process, I need
to to things at two different rates: certain things at the full clock
rate and a slower clock.


I have a basic clock 12 Mhz clock, so I build a clock-divider.


But, as I know I will need that slower clock in multiple places, my idea
would be to have a seperate process for creating the 1 Khz clock and
feed that into the processes that need that.


My code is below.


I have two questions from a generic "how to design a syncrounous system"
one.

1/ Is this the right way to do this?

Does it make sence to create one clock-divider as a seperate process and
feed then then into other process? (so not to have to synthesiser to
create one per every process that needs one).

Or can I just code the clock-divider into every process that needs that.
(Perhaps the synthesier will optimise the design anyway and do all the
work for me).


2/ From a timing point of view, the div12000-clock output of the clock
divider sits after some logic and is then feed into the other processes.
I guess this will create some delay.

But in the processes that actually use that clock (processes "a" and "b"
in my example) , the vhdl code to check on that signal sits behind a
"rising_edge(clk_in)", which is -if I am correct- a very short timespan.

Will this not result in timing-issues?
Can I be sure that the "slowclock = 1" will arrive in process "a" and
"b" fast enough.

Or will the synthesiser do special things to make sure it will. (perhaps
delay clk_in in the processes "a" and "b" a little bit).



Or, in a more generic sence,

When doing an initial design of a syncrounous system, do you need to
take timing-issues like this in account?

Or can I just assume there is zero-delay in all processes and let
timing-issues be dealt with by the synthesizer?

(I did read some comments that it will at least check certain elements
concerning timing of the design).



I did a very interesting post in a forum that clock-signals in a FPGA
are special and that clock-signals pass over special "lanes" (or
whatever the correct term is) so they arrive at all places in the chip
at the same moment.


It would however be interesting to find some information on how to deal
with clock-signals (especially if you create them yourself in a
clock-divider) in a syncronous design.




--- cut here --- cut here --- cut here ---

clockdiv12000: process (clk_in) is
begin
if (rising_edge(clk_in) then
if (counter = 11999) then
counter <= 0;
slowclock <= '1';
else
counter <= counter + 1;
slowclock <= '0';
end if;
end if; -- end rising_edge
end process clockdiv8000;


a: process (clk_in, slowclock, in1, in2) is
begin

if (rising_edge(clk_in) then

(do some stuff at 8 Mhz clock)

if (slowclock = '1') then
(do some stuff at 1 Khz clock)
end if;
end if;

end process a;


b: process (clk_in, slowclock, in3, in4) is
begin

if (rising_edge(clk_in) then

(do some stuff at 8 Mhz clock)

if (slowclock = '1') then
(do some stuff at 1 Khz clock)
end if;
end if;

end process b;

What is important in your example is not the details of the code, but
more the details of the signal flow. If every process in a given clock
domain only depends on the signals in that domain, then you don't have
any clock boundary crossing problems. But in your text you ask about
this so it is clear that signals cross clock domain boundaries.

When that is true you have timing issues that can be very hard to solve.
Rather than thinking in terms of the code, think in terms of the
hardware. Each gate, FF and even routing path has different delays from
others and these delays vary with process, voltage and temperature
(PVT). They can vary in different amounts since the die temperature is
not uniform. The slow clock is going to follow the fast clock by an
unknown (but relatively small) amount of time. This time will be very
dependent on PVT. This is very hard to deal with unless you do things
like generate the slow clock from the falling edge of the fast clock to
allow a half clock cycle offset. While improving the available delay on
fast to slow clock domain paths this reduces the available delay time on
slow to fast paths. These timing delays are very hard to verify in
static timing analysis. However, it can be made to work. Soooo....

What is left? The other alternative is to just use one clock for the
entire design and to run the other "clock domains" from that same clock,
but using a gated enable at the rate of your slow clock. Kevin has
already explained this pretty well. I'm not sure what I could add other
than this *greatly* simplifies timing analysis since every timing path
is a full clock cycle with nothing special to specify.

--

Rick C
 
Hi Kevin,


I must say that learning FPGAs just for books seams to be not very easy.
There seams to be all kind of "need to knows" that are usually not
covered in the books, so thank you, but to you and to Rick, for your
replies.



On 10-06-16 12:58, KJ wrote:
On Friday, June 10, 2016 at 2:53:55 AM UTC-4, kristoff wrote:
I have two questions from a generic "how to design a syncrounous system"
one.

1/ Is this the right way to do this?

If your target is an ASIC, then the answer might be yes. Otherwise, the answer is no. The way to do it is to create clock enable signals and then use them to enable the processes like this
process(My_high_speed_clock)
begin
if rising_edge(My_high_speed_clock)
if (Clock_Enable_1KHz = '1') then
...put your stuff that would be clocked by 1kHz here
end if;
end if;
end process;

OK. In the mean time, I did some more reading on the topic of clocks,
gated clocks and Clock-enable signals.


Now, looking at your code, I do not see to much different between your
code (and what I found in other places on the web) and what I have.


Only two things:
- My signal is called "slow clock", your is called "Clock_Enable") but
as I do not see that in the list VHDL reserved works, I guess that is
irrelevant.

- In my process, I have both VHDL code running at the full clock speed,
and other code in the "clock_enabled" clause.

So am I correct to assume that for VHDL to be synthesized to a
clock-enabled design, I can only have VHDL code in the
"Clock_Enabled_1Khz" part and no other things running at the full
clock-speed?





Or can I just code the clock-divider into every process that needs that.
(Perhaps the synthesier will optimise the design anyway and do all the
work for me).

From a code maintenance standpoint, it would be better to create the divider once and use it everywhere.
Again, the divider would be generating a clock enable signal to use,
not an actual clock signal.

OK. Got that.



2/ From a timing point of view, the div12000-clock output of the clock
divider sits after some logic and is then feed into the other processes.
I guess this will create some delay.

Again, if targeting an ASIC, the answer might be yes. Otherwise, the answer is no. You will be creating timing problems that you can't actually fix, only get lucky at best to get it to sometimes work.

Well, I was kind of sceptical about this myself too,

I remember reading about zero-delay in the RTL design stage of the
design, so I think that confused me.




Or, in a more generic sence,
When doing an initial design of a syncrounous system, do you need to
take timing-issues like this in account?
Consider clocking and timing upfront on every design.

Looks logical.

I think I might first need a good book on how to design syncronous
systems and switch over to how to implement this is a CPLS or FPGA
afterwards.



I did a very interesting post in a forum that clock-signals in a FPGA
are special and that clock-signals pass over special "lanes" (or
whatever the correct term is) so they arrive at all places in the chip
at the same moment.

Not exactly the same time, but they arrive quickly enough that they guarantee that no matter which flip flops get connected, the clock will get there first.

But then do we not have the same issue here with the clock-enabled signals?





Synchronous designs use a single clock, not multiple. If something
needs to happen periodically at a lower rate, you generate a clock
enable signal using a counter.

OK. That's also what I had in my mind, so that's good :)



> Kevin Jennings
 
On Saturday, June 11, 2016 at 8:06:56 AM UTC-4, kristoff wrote:
process(My_high_speed_clock)
begin
if rising_edge(My_high_speed_clock)
if (Clock_Enable_1KHz = '1') then
...put your stuff that would be clocked by 1kHz here
end if;
end if;
end process;

- In my process, I have both VHDL code running at the full clock speed,
and other code in the "clock_enabled" clause.

So am I correct to assume that for VHDL to be synthesized to a
clock-enabled design, I can only have VHDL code in the
"Clock_Enabled_1Khz" part and no other things running at the full
clock-speed?

Not quite sure what you mean. You certainly can have signals being assigned outside of the "if (Clock_Enable_1KHz = '1') then" block, if you want but if you're trying to create signals that can only change when a hypothetical 1kHz clock signal comes along, then yes, everything goes inside the "if (Clock_Enable_1KHz = '1') then".

Fundamentally, you're describing logic that gets clocked by the clock signal that is listed in "if rising_edge(...) then", but making it operate in such a way that it appears to only be clocked by a 1 KHz clock instead. The actual design is not being clocked with the 1KHz clock, but it is operating as if it was...that's not the same thing, but it is usually all that is actually required.

I did a very interesting post in a forum that clock-signals in a FPGA
are special and that clock-signals pass over special "lanes" (or
whatever the correct term is) so they arrive at all places in the chip
at the same moment.

Not exactly the same time, but they arrive quickly enough that they guarantee that no matter which flip flops get connected, the clock will get there first.

But then do we not have the same issue here with the clock-enabled signals?
No, and here is the difference:
- The clock enable is just another signal input into the cloud of logic that gets fed into the D input of a flip flop that gets clocked by a high speed clock. That high speed clock, can be guaranteed by the FPGA/CPLD manufacturer to arrive at the clock input of every flip flop on the die without violating setup or hold time violations due to skew on that clock signal itself. In order to get this guarantee you simply need to follow the FPGA/CPLD rules and use one of the specified clock input pins of the device or use one of the internal PLLs.

- When you use an internally generated signal to clock a flip flop (such as generating a 1KHz signal and using the rising edge of that signal) now there are no guarantees that the 1KHz clock will actually arrive when it should. The data input to the flip flop might actually beat the clock. In that situation, there is nothing you can do to fix the design in a way that you can guarantee will work under all temperature and supply voltage conditions.

Kevin Jennings
 
Hi Rick,


As noted in my answer to Kevin. Thanks for your reply.


On 10-06-16 14:52, rickman wrote:

What is important in your example is not the details of the code, but
more the details of the signal flow. If every process in a given clock
domain only depends on the signals in that domain, then you don't have
any clock boundary crossing problems. But in your text you ask about
this so it is clear that signals cross clock domain boundaries.

My question was in the first place intented to get an idea of how to do
syncronous design.



When that is true you have timing issues that can be very hard to solve.
Rather than thinking in terms of the code, think in terms of the
hardware.

My intention was to think about grouping / reusing code (hardware).


Each gate, FF and even routing path has different delays from
others and these delays vary with process, voltage and temperature
(PVT). They can vary in different amounts since the die temperature is
not uniform. The slow clock is going to follow the fast clock by an
unknown (but relatively small) amount of time. This time will be very
dependent on PVT.


OK, let me see if I understand this correctly.

- Concider "t=0" when the counter in the clock-divider process reaches
the value to trigger the "clock_enable = 1" signale
- Concider "t=1" is the next timeslot, when clock_enable is set back to 0.



So can I then assume that the processes driven by the clock-enable
signal (processes "a" and "b" in my example) are NOT fired at "t=0", but
at "t=1"; this due to the fact that the clock_enable signal arrives at
"a" and "b" with a certain delay, when the "rising_edge(clk)" has
already passed.




... This is very hard to deal with unless you do things
like generate the slow clock from the falling edge of the fast clock to
allow a half clock cycle offset.

This is also something I had I had thought about :)



What is left? The other alternative is to just use one clock for the
entire design and to run the other "clock domains" from that same clock,
but using a gated enable at the rate of your slow clock. Kevin has
already explained this pretty well. I'm not sure what I could add other
than this *greatly* simplifies timing analysis since every timing path
is a full clock cycle with nothing special to specify.
OK. I think I got that.

Thanks!


Cheerio! Kr. Bonne.
 
So am I correct to assume that for VHDL to be synthesized to a
clock-enabled design, I can only have VHDL code in the
"Clock_Enabled_1Khz" part and no other things running at the full
clock-speed?

You can mix to two in the same process. Extending the previous template it can look like this

process(My_high_speed_clock)
begin
if rising_edge(My_high_speed_clock)
...put your stuff that would be clocked by 12 MHz here
if (Clock_Enable_1KHz = '1') then
...put your stuff that would be clocked by 1kHz here
end if;
end if;
end process;

Whether or not you mix them or put them in separate processes is more a matter of grouping things that belongs together such that the code becomes modular (better code readability/maintenance and less error-prone). There are different ways that things can belong together and grouping things by functionality is the best thing you can do. This is also known as functional cohesion. Grouping thing because they run at 1 KHz but has nothing else in common is known as logical cohesion and is among the worst things you can do. With good/bad I'm referring to the benefits of modularity. It might be that a poor type of cohesion results in other benefits such as better resource utilization.

/Lars
 
On 6/11/2016 8:25 AM, kristoff wrote:
Hi Rick,


As noted in my answer to Kevin. Thanks for your reply.


On 10-06-16 14:52, rickman wrote:

What is important in your example is not the details of the code, but
more the details of the signal flow. If every process in a given clock
domain only depends on the signals in that domain, then you don't have
any clock boundary crossing problems. But in your text you ask about
this so it is clear that signals cross clock domain boundaries.

My question was in the first place intented to get an idea of how to do
syncronous design.

My bad, see below. I think you are doing pretty well.


When that is true you have timing issues that can be very hard to solve.
Rather than thinking in terms of the code, think in terms of the
hardware.

My intention was to think about grouping / reusing code (hardware).


Each gate, FF and even routing path has different delays from
others and these delays vary with process, voltage and temperature
(PVT). They can vary in different amounts since the die temperature is
not uniform. The slow clock is going to follow the fast clock by an
unknown (but relatively small) amount of time. This time will be very
dependent on PVT.



OK, let me see if I understand this correctly.

- Concider "t=0" when the counter in the clock-divider process reaches
the value to trigger the "clock_enable = 1" signale
- Concider "t=1" is the next timeslot, when clock_enable is set back to 0.



So can I then assume that the processes driven by the clock-enable
signal (processes "a" and "b" in my example) are NOT fired at "t=0", but
at "t=1"; this due to the fact that the clock_enable signal arrives at
"a" and "b" with a certain delay, when the "rising_edge(clk)" has
already passed.




... This is very hard to deal with unless you do things
like generate the slow clock from the falling edge of the fast clock to
allow a half clock cycle offset.

This is also something I had I had thought about :)



What is left? The other alternative is to just use one clock for the
entire design and to run the other "clock domains" from that same clock,
but using a gated enable at the rate of your slow clock. Kevin has
already explained this pretty well. I'm not sure what I could add other
than this *greatly* simplifies timing analysis since every timing path
is a full clock cycle with nothing special to specify.
OK. I think I got that.

Thanks!

Sorry, Kristoff, I didn't see your code correctly (or maybe just didn't
pay attention). Your code *is* using clock enables. So the entire chip
is running from one clock, clk_in.

When I use clock enables I name all signals as xyz_en or something
similar rather than calling them "xyz_clock".

In this new context the delays are all going to be relative to clk_in
and can be fully analyzed by static timing analysis.

Looking at your code more carefully, I see you are including slowclock,
in1, in2, in3, in4 in your sensitivity lists. None of these signals
should be firing the process since nothing will happen unless it is also
the rising edge of clk_in (which it won't). Once you remove these
signals from your sensitivity lists look at how the code functions again
and see if you still have questions. This should make it clear that the
slowclock signal is just another data signal and not a clock in the real
sense of the word. So you analyze its timing the same as the other
non-clock signals.

Do you know how to set constraints for static timing analysis?

--

Rick C
 
On 6/11/2016 7:06 AM, kristoff wrote:
Hi Kevin,


I must say that learning FPGAs just for books seams to be not very easy.
There seams to be all kind of "need to knows" that are usually not
covered in the books, so thank you, but to you and to Rick, for your
replies.
As a newbie I also agree, most books, and I have several books, they are
either are too vague design books, or most jump right into the code but
leave out a lot of information, they give a lot of details but leave out
the overall picture.

I assume one will just have to work with full working examples and read
through and them do small hardware projects using the knowledge and
code from prior working projects, and see how things turn out.

At some point I expect that things will start making sense and one can
start making small hardware projects without copy and paste, but that
point is nowhere here for now.

--
Cecil - k5nwa
 
On Saturday, June 11, 2016 at 3:24:43 PM UTC-4, rickman wrote:
There is one important concept that you will need when you are
simulating VHDL circuits, that is the delta delay. The delta delay is
used to deal with the problem of simulating concurrent logic.

When a signal changes, any process (which includes each concurrent logic
statement as they are also processes) that depends on that signal runs
simultaneously. However, in a simulator "simultaneously" is emulated by
evaluating each process one at a time. If the outputs from one process
are used by another the results will depend on which process is run first!

The part about "the results will depend on which process is run first!" is not correct. At least not with VHDL.

proc_A: process (clk) begin
if rising_edge(clk) then
A <= B + C;
end if;
end process proc_A;

proc_D: process (clk) begin
if rising_edge(clk) then
D <= A + C;
end if;
end process proc_D;

When clk changes both assignments are evaluated. If proc_A runs first,
it becomes A' <= B + C', where the ' indicates the new version of each
signal. proc_D will be evaluated next as D' <= A' + C' or <= B + C' +
C'; So far, so good.

But what if proc_D runs first? It will assign D' <= A + C' or <= B + C
+ C'; clearly a different result.

This is wrong. Both processes are sensitive only to changes in the signal clk. Because of the 'if rising_edge(clk)', the statements that assign to 'A' and 'D' will only get executed on the rising edge of clk. Neither signal will get updated until all processes that were run on that particular cycle have been executed and suspend.

Using any compliant VHDL simulator, there will be no differences in the values of 'A' and 'D' based upon which process gets executed first.

The way to get around this is to use delta delays for all signal
assignments. A delta delay can be thought of as smaller than the time
resolution of the simulation. So it won't show up as a time delay
anywhere, but it affects the ordering of all processes in the system.

This is what the simulator does, not the user. Is that what you're trying to describe??

In the above example when clk rises at time t=0 it triggers both
processes to run. However, the assignments will be queued for time
t=0+d where d represents a delta delay. So once all the processes have
run at time t=0, the signals will be updated to their new values at
t=0+d which will give the result shown in the second case above.

This is correct...but directly contradicts what you had said earlier about the values depending on the order of execution of the processes which is not correct for VHDL. I'm guessing that you were talking about some hypothetical language model that looks like VHDL (since that's what your two example processes look like), but in fact really is not (since it updates the signals at the end of each process, which is not what the VHDL LRM specifies).

I don't know if you have any confusion about this, but I am laid up
after a hip surgery and have nothing better to do... lol

Maybe you took too many pills before you posted (kidding, hope you get well soon).

Kevin Jennings
 
On Saturday, June 11, 2016 at 1:17:48 PM UTC-4, kristoff wrote:
I still have some issues trying to understand how it really all fits
together.

From how I understand it, -and feel free to correct me if I am wrong-
how the VHDL synthesizer translates into an actual hardware design is by
looking into the VHDL code and searching for certain "patterns" (called
"templates" ???) in the code that it known about and recognises.

So, if it sees "if rising_edge(My_high_speed_clock)" followed by a "if
(Clock_Enable_1KHz = '1')", it recognises this as a clock-enabled circui
and translates this into (say) a "D flip-flop with enable" hardware
component.

Almost. Synthesis tools do look for something to match a template. When it sees a process with "if rising_edge(...) then" it knows that a flip flop is needed. It doesn't really care about the part that makes it look like a clock enabled flip flop. The clock enable portion can also be implemented as part of the logic that leads into the 'D' input of the flip flop. There are also templates that infer memory blocks and other things as well. You're probably close enough though with your understanding.

Rick's message got me thinking.

I guess the best way to do this is-

- in the clock-divider process, set the clock_enable signal not on the
rising edge, but on the *falling* edge of the clock

- in the processes that use that clock_enable, use the *rising* edge.

That way, even if there is a delay in the propagation of the
clock_enable signal from the clock-divider to the other processes (as it
is not a "clock" signal), as long as it less then half of a clock-cycle;
this should work.

This is not a good approach since now the clock enable signal will have less than 1/2 of a clock cycle to get to where it needs to go rather than having a full clock cycle. There is nothing at all special about the clock enable signal as compared to any other signal that flows into the logic. When you use global clocks you are guaranteed that every flip flop output (clock enable being an example) will not arrive at any destination flip flop input (i.e. where clock enable is being used) before the rising edge of the clock. That means that you are guaranteed one full clock cycle to get from flip flop output to the next flip flop input with whatever logic you describe. Whether you describe logic for a clock enabled flip flop or not, it doesn't matter.

Short answer is that if you ever feel the need to use both edges of the clock...most likely you're not going about your design in the correct manner. Synchronous logic design not only uses only one clock, but only one edge of that one clock. Having said that, there are cases when both edges are used and that is the correct thing to do...but what you've described so far is not an example.
Kevin Jennings
 
Kevin,



On 11-06-16 18:13, KJ wrote:

process(My_high_speed_clock)
begin
if rising_edge(My_high_speed_clock)
if (Clock_Enable_1KHz = '1') then
...put your stuff that would be clocked by 1kHz here
end if;
end if;
end process;

- In my process, I have both VHDL code running at the full clock speed,
and other code in the "clock_enabled" clause.

So am I correct to assume that for VHDL to be synthesized to a
clock-enabled design, I can only have VHDL code in the
"Clock_Enabled_1Khz" part and no other things running at the full
clock-speed?

Not quite sure what you mean. You certainly can have signals being assigned
outside of the "if (Clock_Enable_1KHz = '1') then" block, if you want
but if you're trying to create signals that can only change when a
hypothetical 1kHz clock signal comes along, then yes, everything
goes inside the "if (Clock_Enable_1KHz = '1') then".

OK. That's clear.


Fundamentally, you're describing logic that gets clocked by the clock
signal that is listed in "if rising_edge(...) then", but making it
operate in such a way that it appears to only be clocked by a 1
KHz clock instead. The actual design is not being clocked with
the 1KHz clock, but it is operating as if it was...that's not the
same thing, but it is usually all that is actually required.

OK then.


I still have some issues trying to understand how it really all fits
together.

From how I understand it, -and feel free to correct me if I am wrong-
how the VHDL synthesizer translates into an actual hardware design is by
looking into the VHDL code and searching for certain "patterns" (called
"templates" ???) in the code that it known about and recognises.

So, if it sees "if rising_edge(My_high_speed_clock)" followed by a "if
(Clock_Enable_1KHz = '1')", it recognises this as a clock-enabled circui
and translates this into (say) a "D flip-flop with enable" hardware
component.



So I had the (apparently wrong) idea that -for some reason- the
synthesier template required that the VHDL process cannot not have other
stuff outside the "if (Clock_Enable = '1')" clause.

Anycase, it's cleared up now. Thanks!




I did a very interesting post in a forum that clock-signals in a FPGA
are special and that clock-signals pass over special "lanes" (or
whatever the correct term is) so they arrive at all places in the chip
at the same moment.
Not exactly the same time, but they arrive quickly enough that they guarantee that no matter which flip flops get connected, the clock will get there first.

But then do we not have the same issue here with the clock-enabled signals?
No, and here is the difference:
- The clock enable is just another signal input into the cloud of logic that gets fed into the D input of a flip flop that gets clocked by a high speed clock. That high speed clock, can be guaranteed by the FPGA/CPLD manufacturer to arrive at the clock input of every flip flop on the die without violating setup or hold time violations due to skew on that clock signal itself. In order to get this guarantee you simply need to follow the FPGA/CPLD rules and use one of the specified clock input pins of the device or use one of the internal PLLs.
- When you use an internally generated signal to clock a flip flop (such as generating a 1KHz signal and using the rising edge of that signal) now there are no guarantees that the 1KHz clock will actually arrive when it should. The data input to the flip flop might actually beat the clock. In that situation, there is nothing you can do to fix the design in a way that you can guarantee will work under all temperature and supply voltage conditions.

Rick's message got me thinking.

I guess the best way to do this is-

- in the clock-divider process, set the clock_enable signal not on the
rising edge, but on the *falling* edge of the clock

- in the processes that use that clock_enable, use the *rising* edge.

That way, even if there is a delay in the propagation of the
clock_enable signal from the clock-divider to the other processes (as it
is not a "clock" signal), as long as it less then half of a clock-cycle;
this should work.


Correct ?


Kevin Jennings
Cheerio! Kr. Bonne.
 
Hi Cecil,


On 11-06-16 17:25, Cecil Bayona wrote:

I must say that learning FPGAs just for books seams to be not very easy.
There seams to be all kind of "need to knows" that are usually not
covered in the books, so thank you, but to you and to Rick, for your
replies.

As a newbie I also agree, most books, and I have several books, they are
either are too vague design books, or most jump right into the code but
leave out a lot of information, they give a lot of details but leave out
the overall picture.

For me, the problem is that I really never learned much about digital
logic, I studied electronics some 25 years ago when we already had
microcontrollers (my thesis was with a 8051).

We did learn about basic digital logic (and, or, not, ...), we never
really learned how to solve a problem with it.

If you had an issue that involved some kind of "logic" more complex then
a couple of 74xx ICs and combinational logic, you simply used a
microcontroller and solved it that way.

We never really learned about thinks like sequential logic, timing,
clocks, etc, ... or how to solve a technical issue with digital logic
components; and ... this is what I need now.

Certain concepts used in "programming" (e.g. the idea of a statemachine)
are also usefull in sequencial logic, but that's about it. The rest is
-for me- all quite new.



I assume one will just have to work with full working examples and read
through and them do small hardware projects using the knowledge and
code from prior working projects, and see how things turn out.
At some point I expect that things will start making sense and one can
start making small hardware projects without copy and paste, but that
point is nowhere here for now.

I started looking around for websites that offer simple exercises to
learn this.

Perhaps we can share some ideas on exercises we come up ourselfs.


At this time, I have two things I want to rey out:
- first, an I/O extender with SPI.

The SPI-protocol is not that complex and looks to me like a nice example
of "clocked" sequencial logic.

I think it might be doable, to create a VHDL design/circuit that allow
you to set or clear output pins on a FPGA/CPLD, based on commands
issued via SPI (from a microcontroller).


- a lot more difficult (perhaps as a "final exercise") is this:
https://www.youtube.com/watch?v=35zLnS3fXeA

This is a very simple broadboard based 8-bit processor (which seams to
be the "SAP" architecture used in quite a number of text-book on
microprocessor architecture) completely implemented in 74xx ICs.


I currently how no idea how easy or difficult this will be, but perhaps
duplicating this in VHDL would be the ultimate "final test" exercise :)




Do you -or somebody else- have ideas for exercises that might be
interesting to learn how to solve actual real problems with logic?





By the way, I notice you ham callsign in your messages.
It's nice to see a fellow ham interested in FPGAs and VHDL. :)




Kristoff (ON1ARF)
 
On 6/11/2016 1:17 PM, kristoff wrote:
Kevin,



On 11-06-16 18:13, KJ wrote:

process(My_high_speed_clock)
begin
if rising_edge(My_high_speed_clock)
if (Clock_Enable_1KHz = '1') then
...put your stuff that would be clocked by 1kHz here
end if;
end if;
end process;

- In my process, I have both VHDL code running at the full clock speed,
and other code in the "clock_enabled" clause.

So am I correct to assume that for VHDL to be synthesized to a
clock-enabled design, I can only have VHDL code in the
"Clock_Enabled_1Khz" part and no other things running at the full
clock-speed?

Not quite sure what you mean. You certainly can have signals being
assigned
outside of the "if (Clock_Enable_1KHz = '1') then" block, if you want
but if you're trying to create signals that can only change when a
hypothetical 1kHz clock signal comes along, then yes, everything
goes inside the "if (Clock_Enable_1KHz = '1') then".

OK. That's clear.


Fundamentally, you're describing logic that gets clocked by the clock
signal that is listed in "if rising_edge(...) then", but making it
operate in such a way that it appears to only be clocked by a 1
KHz clock instead. The actual design is not being clocked with
the 1KHz clock, but it is operating as if it was...that's not the
same thing, but it is usually all that is actually required.

OK then.


I still have some issues trying to understand how it really all fits
together.

From how I understand it, -and feel free to correct me if I am wrong-
how the VHDL synthesizer translates into an actual hardware design is by
looking into the VHDL code and searching for certain "patterns" (called
"templates" ???) in the code that it known about and recognises.

So, if it sees "if rising_edge(My_high_speed_clock)" followed by a "if
(Clock_Enable_1KHz = '1')", it recognises this as a clock-enabled circui
and translates this into (say) a "D flip-flop with enable" hardware
component.

I don't know exactly how the VHDL tools parse and interpret the code to
produce logic. What I do know is that templates are not always used
since there are many ways to skin a given cat. For example you can write:

q <= d when rising_edge(clk);

to infer a register. I don't think this is "template matching" in the
sense of pattern matching. BTW, the above will work, but is not
recommended for mostly clarity reasons. Not many are familiar with it
and will be scratching their heads when they see it, at least for a bit.


So I had the (apparently wrong) idea that -for some reason- the
synthesier template required that the VHDL process cannot not have other
stuff outside the "if (Clock_Enable = '1')" clause.

Anycase, it's cleared up now. Thanks!




I did a very interesting post in a forum that clock-signals in a FPGA
are special and that clock-signals pass over special "lanes" (or
whatever the correct term is) so they arrive at all places in the chip
at the same moment.
Not exactly the same time, but they arrive quickly enough that they
guarantee that no matter which flip flops get connected, the clock
will get there first.

But then do we not have the same issue here with the clock-enabled
signals?
No, and here is the difference:
- The clock enable is just another signal input into the cloud of
logic that gets fed into the D input of a flip flop that gets clocked
by a high speed clock. That high speed clock, can be guaranteed by
the FPGA/CPLD manufacturer to arrive at the clock input of every flip
flop on the die without violating setup or hold time violations due to
skew on that clock signal itself. In order to get this guarantee you
simply need to follow the FPGA/CPLD rules and use one of the specified
clock input pins of the device or use one of the internal PLLs.
- When you use an internally generated signal to clock a flip flop
(such as generating a 1KHz signal and using the rising edge of that
signal) now there are no guarantees that the 1KHz clock will actually
arrive when it should. The data input to the flip flop might actually
beat the clock. In that situation, there is nothing you can do to fix
the design in a way that you can guarantee will work under all
temperature and supply voltage conditions.

Rick's message got me thinking.

I guess the best way to do this is-

- in the clock-divider process, set the clock_enable signal not on the
rising edge, but on the *falling* edge of the clock

- in the processes that use that clock_enable, use the *rising* edge.

That way, even if there is a delay in the propagation of the
clock_enable signal from the clock-divider to the other processes (as it
is not a "clock" signal), as long as it less then half of a clock-cycle;
this should work.


Correct ?

When I was talking about using the negative edge of the clock I was
thinking you were using the slow clock as an actual clock to the FFs
where you want to avoid race condition problems. When using a clock
enable both the design of the chip (clock skew vs. setup and hold times)
and the tools assure the timing will work provided the max path delay is
less than the clock cycle time minus the setup and hold time of the FFs.

Do you understand that using the negative edge of the clock to generate
the enable will reduce your slack time in the enable path? Even for the
slow clock enable, it only has one clock cycle to be distributed and
needs all the time you can give it. Generating it from the same clock
edge as you are using elsewhere gives you the longest possible path
delay time without having to worry about hold time.

I'm sorry if I confused you.

--

Rick C
 
Hi Rick,

On 11-06-16 16:00, rickman wrote:

My question was in the first place intented to get an idea of how to do
syncronous design.

My bad, see below. I think you are doing pretty well.

No problem. :)


Last week, I talked to somebody who works in a company that does ASIC
design and he said that -althou VHDL is a high-level language- you need
to keep in mind that this all gets turned into hardware.

"always try to understand how the hardware that actually does the job
actually works".

So, as already mentioned, I really appriciate what you do and the time
you take to explain the background of all this!



Sorry, Kristoff, I didn't see your code correctly (or maybe just didn't
pay attention). Your code *is* using clock enables. So the entire chip
is running from one clock, clk_in.
When I use clock enables I name all signals as xyz_en or something
similar rather than calling them "xyz_clock".

OK. Granted.

I must still learn the naming-conventions of FPGA :)





In this new context the delays are all going to be relative to clk_in
and can be fully analyzed by static timing analysis.

Sofar I have concentrated on understand VHDL and the underlaying
concepts. I always try to do basic research myself and try to solve it
myself before taking up other peoples time.

I have not really focused on the simulation part. I will try it out and
if it does not work, I will come back to the forum.





Looking at your code more carefully, I see you are including slowclock,
in1, in2, in3, in4 in your sensitivity lists. None of these signals
should be firing the process since nothing will happen unless it is also
the rising edge of clk_in (which it won't). Once you remove these
signals from your sensitivity lists look at how the code functions again
and see if you still have questions.

Yes. You are correct.

Thanks for noting that.



... This should make it clear that the
slowclock signal is just another data signal and not a clock in the real
sense of the word. So you analyze its timing the same as the other
non-clock signals.

OK. thx!

I understand and use the "clock_enable" naming-convension in the future. :)



Cheerio! Kr. Bonne.
 
On 6/11/2016 2:35 PM, kristoff wrote:
Hi Cecil,


On 11-06-16 17:25, Cecil Bayona wrote:

I must say that learning FPGAs just for books seams to be not very easy.
There seams to be all kind of "need to knows" that are usually not
covered in the books, so thank you, but to you and to Rick, for your
replies.

As a newbie I also agree, most books, and I have several books, they are
either are too vague design books, or most jump right into the code but
leave out a lot of information, they give a lot of details but leave out
the overall picture.


For me, the problem is that I really never learned much about digital
logic, I studied electronics some 25 years ago when we already had
microcontrollers (my thesis was with a 8051).

We did learn about basic digital logic (and, or, not, ...), we never
really learned how to solve a problem with it.

If you had an issue that involved some kind of "logic" more complex then
a couple of 74xx ICs and combinational logic, you simply used a
microcontroller and solved it that way.

We never really learned about thinks like sequential logic, timing,
clocks, etc, ... or how to solve a technical issue with digital logic
components; and ... this is what I need now.

Certain concepts used in "programming" (e.g. the idea of a statemachine)
are also usefull in sequencial logic, but that's about it. The rest is
-for me- all quite new.

There is one important concept that you will need when you are
simulating VHDL circuits, that is the delta delay. The delta delay is
used to deal with the problem of simulating concurrent logic.

When a signal changes, any process (which includes each concurrent logic
statement as they are also processes) that depends on that signal runs
simultaneously. However, in a simulator "simultaneously" is emulated by
evaluating each process one at a time. If the outputs from one process
are used by another the results will depend on which process is run first!

proc_A: process (clk) begin
if rising_edge(clk) then
A <= B + C;
end if;
end process proc_A;

proc_D: process (clk) begin
if rising_edge(clk) then
D <= A + C;
end if;
end process proc_D;

When clk changes both assignments are evaluated. If proc_A runs first,
it becomes A' <= B + C', where the ' indicates the new version of each
signal. proc_D will be evaluated next as D' <= A' + C' or <= B + C' +
C'; So far, so good.

But what if proc_D runs first? It will assign D' <= A + C' or <= B + C
+ C'; clearly a different result.

The way to get around this is to use delta delays for all signal
assignments. A delta delay can be thought of as smaller than the time
resolution of the simulation. So it won't show up as a time delay
anywhere, but it affects the ordering of all processes in the system.

In the above example when clk rises at time t=0 it triggers both
processes to run. However, the assignments will be queued for time
t=0+d where d represents a delta delay. So once all the processes have
run at time t=0, the signals will be updated to their new values at
t=0+d which will give the result shown in the second case above.

BTW, Verilog doesn't use delta delays, so I don't know how they get
consistent and accurate results from their simulations.

I don't know if you have any confusion about this, but I am laid up
after a hip surgery and have nothing better to do... lol


I assume one will just have to work with full working examples and read
through and them do small hardware projects using the knowledge and
code from prior working projects, and see how things turn out.
At some point I expect that things will start making sense and one can
start making small hardware projects without copy and paste, but that
point is nowhere here for now.

I started looking around for websites that offer simple exercises to
learn this.

Perhaps we can share some ideas on exercises we come up ourselfs.


At this time, I have two things I want to rey out:
- first, an I/O extender with SPI.

The SPI-protocol is not that complex and looks to me like a nice example
of "clocked" sequencial logic.

SPI is very simple indeed, but in general well thought out. The labels
clearly indicate the direction of signal flow and the clocking avoids
race conditions if used properly. The down side is that it is a bit
more flexible than needed so it can be a bit tricky to set up.


I think it might be doable, to create a VHDL design/circuit that allow
you to set or clear output pins on a FPGA/CPLD, based on commands
issued via SPI (from a microcontroller).

When you say "commands", usually the I/O bits are set/cleared directly
from the data shifted through the SPI port. There is normally the shift
register that receives the serial data (and provides for shifting data
out) which is transferred to the output register when the select line is
deasserted.


- a lot more difficult (perhaps as a "final exercise") is this:
https://www.youtube.com/watch?v=35zLnS3fXeA

This is a very simple broadboard based 8-bit processor (which seams to
be the "SAP" architecture used in quite a number of text-book on
microprocessor architecture) completely implemented in 74xx ICs.

That might be an ok project, but when it is done, what do you have?
Just an exercise. You might want to design some pieces that will be
useful to you in the future.


I currently how no idea how easy or difficult this will be, but perhaps
duplicating this in VHDL would be the ultimate "final test" exercise :)




Do you -or somebody else- have ideas for exercises that might be
interesting to learn how to solve actual real problems with logic?

A reasonably simple example would be a basic, fixed size UART, say 8
bits, no parity, one stop bit. Design the transmitter and receiver
separately and test by connecting them together and shipping characters
across. Equally important is the test bench used to test your design.
You need to learn how to construct simple and yet powerful test benches
to stimulate your designs and verify the output. It is not uncommon for
the test bench to be as complex as the design you are testing, but
hopefully can be done more simply. In this case you can use the UART
transmitter to test the UART receiver and vice versa. The test bench
only needs to stimulate the parallel input/output and the control
strobes. It also does not need to be synthesizable and so can be
written more like a standard sequential program.

Once you have that working correctly, you can add programmable controls
for the word size, parity and stop bits. That gets a bit more complex
and your test bench will be more complex as well.

Both of these exercises will result in useful code. Often you can use a
simple, fixed size UART in your designs. Other times you will need a
programmable UART so it can be configured by software or changed for
different modes of operation.

Just a thought.

--

Rick C
 
On 6/11/2016 4:13 PM, KJ wrote:
On Saturday, June 11, 2016 at 3:24:43 PM UTC-4, rickman wrote:

There is one important concept that you will need when you are
simulating VHDL circuits, that is the delta delay. The delta delay is
used to deal with the problem of simulating concurrent logic.

When a signal changes, any process (which includes each concurrent logic
statement as they are also processes) that depends on that signal runs
simultaneously. However, in a simulator "simultaneously" is emulated by
evaluating each process one at a time. If the outputs from one process
are used by another the results will depend on which process is run first!


The part about "the results will depend on which process is run first!" is not correct. At least not with VHDL.

proc_A: process (clk) begin
if rising_edge(clk) then
A <= B + C;
end if;
end process proc_A;

proc_D: process (clk) begin
if rising_edge(clk) then
D <= A + C;
end if;
end process proc_D;

When clk changes both assignments are evaluated. If proc_A runs first,
it becomes A' <= B + C', where the ' indicates the new version of each
signal. proc_D will be evaluated next as D' <= A' + C' or <= B + C' +
C'; So far, so good.

But what if proc_D runs first? It will assign D' <= A + C' or <= B + C
+ C'; clearly a different result.


This is wrong. Both processes are sensitive only to changes in the signal clk. Because of the 'if rising_edge(clk)', the statements that assign to 'A' and 'D' will only get executed on the rising edge of clk. Neither signal will get updated until all processes that were run on that particular cycle have been executed and suspend.

Using any compliant VHDL simulator, there will be no differences in the values of 'A' and 'D' based upon which process gets executed first.

The way to get around this is to use delta delays for all signal
assignments. A delta delay can be thought of as smaller than the time
resolution of the simulation. So it won't show up as a time delay
anywhere, but it affects the ordering of all processes in the system.


This is what the simulator does, not the user. Is that what you're trying to describe??

In the above example when clk rises at time t=0 it triggers both
processes to run. However, the assignments will be queued for time
t=0+d where d represents a delta delay. So once all the processes have
run at time t=0, the signals will be updated to their new values at
t=0+d which will give the result shown in the second case above.


This is correct...but directly contradicts what you had said earlier about the values depending on the order of execution of the processes which is not correct for VHDL. I'm guessing that you were talking about some hypothetical language model that looks like VHDL (since that's what your two example processes look like), but in fact really is not (since it updates the signals at the end of each process, which is not what the VHDL LRM specifies).


I don't know if you have any confusion about this, but I am laid up
after a hip surgery and have nothing better to do... lol


Maybe you took too many pills before you posted (kidding, hope you get well soon).

As I said in the opening paragraph, I was trying to explain the concept
of delta delay. Now go back and read it again. I doubt Kristoff has
learned about the delta delay yet and might not understand how processes
interact if you don't have unit delays.

--

Rick C
 
To clear up any confusion created if you already have some knowledge of
delta delays in VHDL, read my comments below.

On 6/11/2016 3:24 PM, rickman wrote:
On 6/11/2016 2:35 PM, kristoff wrote:
Hi Cecil,


On 11-06-16 17:25, Cecil Bayona wrote:

I must say that learning FPGAs just for books seams to be not very
easy.
There seams to be all kind of "need to knows" that are usually not
covered in the books, so thank you, but to you and to Rick, for your
replies.

As a newbie I also agree, most books, and I have several books, they are
either are too vague design books, or most jump right into the code but
leave out a lot of information, they give a lot of details but leave out
the overall picture.


For me, the problem is that I really never learned much about digital
logic, I studied electronics some 25 years ago when we already had
microcontrollers (my thesis was with a 8051).

We did learn about basic digital logic (and, or, not, ...), we never
really learned how to solve a problem with it.

If you had an issue that involved some kind of "logic" more complex then
a couple of 74xx ICs and combinational logic, you simply used a
microcontroller and solved it that way.

We never really learned about thinks like sequential logic, timing,
clocks, etc, ... or how to solve a technical issue with digital logic
components; and ... this is what I need now.

Certain concepts used in "programming" (e.g. the idea of a statemachine)
are also usefull in sequencial logic, but that's about it. The rest is
-for me- all quite new.

There is one important concept that you will need when you are
simulating VHDL circuits, that is the delta delay. The delta delay is
used to deal with the problem of simulating concurrent logic.

If delta delays were *not* used...

When a signal changes, any process (which includes each concurrent logic
statement as they are also processes) that depends on that signal runs
simultaneously. However, in a simulator "simultaneously" is emulated by
evaluating each process one at a time. If the outputs from one process
are used by another the results will depend on which process is run first!

proc_A: process (clk) begin
if rising_edge(clk) then
A <= B + C;
end if;
end process proc_A;

proc_D: process (clk) begin
if rising_edge(clk) then
D <= A + C;
end if;
end process proc_D;

Assume C has changed to C' prior to the rising clock edge.

When clk changes both assignments are evaluated. If proc_A runs first,
it becomes A' <= B + C', where the ' indicates the new version of each
signal. proc_D will be evaluated next as D' <= A' + C' or <= B + C' +
C'; So far, so good.

But what if proc_D runs first? It will assign D' <= A + C' or <= B + C
+ C'; clearly a different result.

But VHDL does always make use of delta delays when making signal
assignments... so...

The way to get around this is to use delta delays for all signal
assignments. A delta delay can be thought of as smaller than the time
resolution of the simulation. So it won't show up as a time delay
anywhere, but it affects the ordering of all processes in the system.

In the above example when clk rises at time t=0 it triggers both
processes to run. However, the assignments will be queued for time
t=0+d where d represents a delta delay. So once all the processes have
run at time t=0, the signals will be updated to their new values at
t=0+d which will give the result shown in the second case above.

BTW, Verilog doesn't use delta delays, so I don't know how they get
consistent and accurate results from their simulations.

I don't know if you have any confusion about this, but I am laid up
after a hip surgery and have nothing better to do... lol


I assume one will just have to work with full working examples and read
through and them do small hardware projects using the knowledge and
code from prior working projects, and see how things turn out.
At some point I expect that things will start making sense and one can
start making small hardware projects without copy and paste, but that
point is nowhere here for now.

I started looking around for websites that offer simple exercises to
learn this.

Perhaps we can share some ideas on exercises we come up ourselfs.


At this time, I have two things I want to rey out:
- first, an I/O extender with SPI.

The SPI-protocol is not that complex and looks to me like a nice example
of "clocked" sequencial logic.

SPI is very simple indeed, but in general well thought out. The labels
clearly indicate the direction of signal flow and the clocking avoids
race conditions if used properly. The down side is that it is a bit
more flexible than needed so it can be a bit tricky to set up.


I think it might be doable, to create a VHDL design/circuit that allow
you to set or clear output pins on a FPGA/CPLD, based on commands
issued via SPI (from a microcontroller).

When you say "commands", usually the I/O bits are set/cleared directly
from the data shifted through the SPI port. There is normally the shift
register that receives the serial data (and provides for shifting data
out) which is transferred to the output register when the select line is
deasserted.


- a lot more difficult (perhaps as a "final exercise") is this:
https://www.youtube.com/watch?v=35zLnS3fXeA

This is a very simple broadboard based 8-bit processor (which seams to
be the "SAP" architecture used in quite a number of text-book on
microprocessor architecture) completely implemented in 74xx ICs.

That might be an ok project, but when it is done, what do you have? Just
an exercise. You might want to design some pieces that will be useful
to you in the future.


I currently how no idea how easy or difficult this will be, but perhaps
duplicating this in VHDL would be the ultimate "final test" exercise :)




Do you -or somebody else- have ideas for exercises that might be
interesting to learn how to solve actual real problems with logic?

A reasonably simple example would be a basic, fixed size UART, say 8
bits, no parity, one stop bit. Design the transmitter and receiver
separately and test by connecting them together and shipping characters
across. Equally important is the test bench used to test your design.
You need to learn how to construct simple and yet powerful test benches
to stimulate your designs and verify the output. It is not uncommon for
the test bench to be as complex as the design you are testing, but
hopefully can be done more simply. In this case you can use the UART
transmitter to test the UART receiver and vice versa. The test bench
only needs to stimulate the parallel input/output and the control
strobes. It also does not need to be synthesizable and so can be
written more like a standard sequential program.

Once you have that working correctly, you can add programmable controls
for the word size, parity and stop bits. That gets a bit more complex
and your test bench will be more complex as well.

Both of these exercises will result in useful code. Often you can use a
simple, fixed size UART in your designs. Other times you will need a
programmable UART so it can be configured by software or changed for
different modes of operation.

Just a thought.

--

Rick C
 
Kevin,



On 11-06-16 22:30, KJ wrote:
(...)
Short answer is that if you ever feel the need to use both edges of
the clock...most likely you're not going about your design in the
correct manner. Synchronous logic design not only uses only one
clock, but only one edge of that one clock. Having said that, there
are cases when both edges are used and that is the correct thing to
do...but what you've described so far is not an example.

Very valuable advice.

Thanks! :)



Kevin Jennings
Cheerio! Kr. Bonne.
 
On 6/11/2016 5:51 PM, kristoff wrote:
Kevin,



On 11-06-16 22:30, KJ wrote:
(...)
Short answer is that if you ever feel the need to use both edges of
the clock...most likely you're not going about your design in the
correct manner. Synchronous logic design not only uses only one
clock, but only one edge of that one clock. Having said that, there
are cases when both edges are used and that is the correct thing to
do...but what you've described so far is not an example.

Very valuable advice.

Your SPI interface is one of the places where both edges of the clock
*will* be used. When exchanging data externally you can't control the
clock skew enough to use the same clock edge for shifting data out and
shifting data in. So data is clocked out on one edge and in on the
other to assure adequate setup and hold times.

There are also some interfaces that specify the transmission of data on
both edges of the interface clock. Typically a 2x clock is used, but
you can also use a 1x clock with two sets of FFs clocked on opposite
clock edges. SDRAM memory interfaces typically do this and extra FFs
are included in the IO blocks of many FPGAs for this purpose.

Internally this would never be used in an FPGA.

I had a discussion once with someone laying out a CPU design who was
using the negative clock edge in a pipeline to increase his setup and
hold times. I tried to explain to him that this does not improve the
setup and hold, but in fact reduces the slack time because within 1
clock cycle two setups and two hold times have to be met. Maybe I
wasn't understanding what he was doing, but we never came to an agreement.

--

Rick C
 

Welcome to EDABoard.com

Sponsor

Back
Top