Author Topic: My first FPGA code  (Read 24510 times)

0 Members and 1 Guest are viewing this topic.

Offline lawrence11Topic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 322
  • Country: ca
Re: My first FPGA code
« Reply #100 on: November 26, 2019, 12:14:04 am »
I seem to fail at following directives. I will try implementing the reset after this passes.

Can you post the code emece? Or some of it.
 

Offline emece67

  • Frequent Contributor
  • **
  • !
  • Posts: 614
  • Country: 00
Re: My first FPGA code
« Reply #101 on: November 26, 2019, 12:16:40 am »
.
« Last Edit: August 19, 2022, 02:36:45 pm by emece67 »
 

Offline emece67

  • Frequent Contributor
  • **
  • !
  • Posts: 614
  • Country: 00
Re: My first FPGA code
« Reply #102 on: November 26, 2019, 12:19:39 am »
.
« Last Edit: August 19, 2022, 02:36:52 pm by emece67 »
 

Offline lawrence11Topic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 322
  • Country: ca
Re: My first FPGA code
« Reply #103 on: November 26, 2019, 12:40:38 am »
I read a 50 page document, and more videos.

I'm just slow.

 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9932
  • Country: us
Re: My first FPGA code
« Reply #104 on: November 26, 2019, 12:46:00 am »
c) An always block has a sensitivity list, which means that it wakes up whenever there is a transaction on the signals in its sensitivity list.

And it's worth pointing out again, this sensitivity list only starts processes under simulation.  It has no effect on synthesis even though the synthesizer complains if signals are missing.
 

Offline lawrence11Topic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 322
  • Country: ca
Re: My first FPGA code
« Reply #105 on: November 26, 2019, 12:55:56 am »
I honestly could have been lucky and avoided this, I passed by this solution a bunch of times.

But by then, this murderous line was poisoning my workflow.
 

Offline lawrence11Topic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 322
  • Country: ca
Re: My first FPGA code
« Reply #106 on: November 26, 2019, 01:03:09 am »
Finally, I have attained....
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2812
  • Country: nz
Re: My first FPGA code
« Reply #107 on: November 26, 2019, 02:02:56 am »
Finally, I have attained....

Which dot is yours? I think everybody who has contributed is at the "Trust me, it's complicated" dot.
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 
The following users thanked this post: rstofer

Offline lawrence11Topic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 322
  • Country: ca
Re: My first FPGA code
« Reply #108 on: November 26, 2019, 02:25:55 am »
Well' I'm obviously at the peak. ;)
 

Offline lawrence11Topic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 322
  • Country: ca
Re: My first FPGA code
« Reply #109 on: November 26, 2019, 02:40:35 am »
Ok can we talk a bit about Verilog vs system verilog?

You see in this image, the quick instantiation? Well that is only a system verilog feature. So If I dump verilog right now for system veriog, can I just do EXACTLY what I would do usually but use these quick instantiations? I dont wanna have ti setup anything complicated either in simulation or synthesis.



 

Offline Bassman59

  • Super Contributor
  • ***
  • Posts: 2501
  • Country: us
  • Yes, I do this for a living
Re: My first FPGA code
« Reply #110 on: November 26, 2019, 04:10:31 pm »
c) An always block has a sensitivity list, which means that it wakes up whenever there is a transaction on the signals in its sensitivity list.

And it's worth pointing out again, this sensitivity list only starts processes under simulation.  It has no effect on synthesis even though the synthesizer complains if signals are missing.
True, but not interesting -- I know you don't believe in simulation, but for those of us who do, the sensitivity list matters.
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9932
  • Country: us
Re: My first FPGA code
« Reply #111 on: November 26, 2019, 06:56:47 pm »
c) An always block has a sensitivity list, which means that it wakes up whenever there is a transaction on the signals in its sensitivity list.

And it's worth pointing out again, this sensitivity list only starts processes under simulation.  It has no effect on synthesis even though the synthesizer complains if signals are missing.
True, but not interesting -- I know you don't believe in simulation, but for those of us who do, the sensitivity list matters.
It is still required for synthesis so it's important to me as well.  It's pretty easy to add logic to a process and overlook including a new signal in the list.  I think it's the 'wake up' part that really needs to be clear:  The sensitivity list tells the simulator to run a process (always block) when any signal in the list changes.  That saves effort for the simulator  If it doesn't need to evaluate the block, it doesn't.  The synthesizer generates logic for the block taking no information from the list.  It's not like the logic under synthesis is 'enabled' by the list as it is in simulation.

Since the simulator cares about the list and the synthesizer doesn't, it is possible to get two different implementations of the logic should a signal be omitted.

The exception is a clocked process where only the clock needs to be in the list because the clock is always changing and changes in the other signals are evaluated when the clock changes.  If the reset signal (if any) is asynchronous, it should be included as well.  I don't think it is necessary for synchronous reset but I include it anyway.

Now we can use process (all) or always @ (*)  to let the simulator and synthesizer work it out for themselves.  I'm still trying to figure out whether this is an improvement or just a change.  If the software doesn't care about the sensitivity list, how about just omitting them instead of using a crutch?
 

Offline Bassman59

  • Super Contributor
  • ***
  • Posts: 2501
  • Country: us
  • Yes, I do this for a living
Re: My first FPGA code
« Reply #112 on: November 26, 2019, 09:57:26 pm »
The exception is a clocked process where only the clock needs to be in the list because the clock is always changing and changes in the other signals are evaluated when the clock changes.  If the reset signal (if any) is asynchronous, it should be included as well.  I don't think it is necessary for synchronous reset but I include it anyway.

Now we can use process (all) or always @ (*)  to let the simulator and synthesizer work it out for themselves.  I'm still trying to figure out whether this is an improvement or just a change.  If the software doesn't care about the sensitivity list, how about just omitting them instead of using a crutch?

For synchronous processes, having a sensitivity list that includes only the clock (and perhaps an async reset) optimizes the simulation. And, I think, it reduces everything to continuous assignments.
If a synchronous process (I'm using VHDL vernacular here) doesn't have the restricted sensitivity list, the simulator won't ignore it until there's an event on the clock. Instead, every time there is an event on any right-hand-side signal, the process gets triggered and everything has to be evaluated. And this is even though the rising_edge(clk) function will return false and no new assignments are scheduled. Imagine how much simulation time is wasted  on such processes.

Combinatorial processes of course are sensitive to every signal on their assignments' right-hand-sides, so the (all) sensitivity list is reasonable.
(Remember that a continuous assignment outside of a process has an inherent sensitivity list that is all of the signals on the right-hand-side of the assignment.)

So specifying the sensitivity list helps the simulator. And, I think, more importantly, it helps the person reading the code by saying, "this process is triggered by this signal." Straightway you see which signal is the clock. It's self-documenting. It's not like there's a lot of typing involved here!

All of which is to say that the statement "synthesis doesn't care about sensitivity" is likely (I haven't actually tested this assertion!) true but not very interesting.
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9932
  • Country: us
Re: My first FPGA code
« Reply #113 on: November 26, 2019, 10:09:18 pm »
It seems to get out of hand when you design a 2 process state machine with 100+ states in the combinatorial process.  The sensitivity list can get lengthy but the only way to keep the synthesizer from nagging is to add every right-hand-side signal.

And, on a different matter, provide a default value for every left-hand-side signal.  This is where I have had the most problems.  The state machine hangs because there is no value for a signal even though the next-state is clearly defined.  Basically, I came up with the idea that 'if it doesn't work, look for missing default values first!'.  This is another place where it is easy to mess up when adding additional logic and output signals.

Of the long list of mistakes a user can make, I suspect I have hit them all.  Maybe I have missed a couple of esoteric problems because I don't use the construct but for everyday logic, I've made them all!  I should get a merit badge...

 

Offline lawrence11Topic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 322
  • Country: ca
Re: My first FPGA code
« Reply #114 on: November 26, 2019, 10:15:53 pm »
One more time
 

Offline Bassman59

  • Super Contributor
  • ***
  • Posts: 2501
  • Country: us
  • Yes, I do this for a living
Re: My first FPGA code
« Reply #115 on: November 26, 2019, 10:56:05 pm »
One more time
The block is clocked by data_clk and data_clk never toggles. If the clock doesn't toggle, pin_1 is never assigned.
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2812
  • Country: nz
Re: My first FPGA code
« Reply #116 on: November 26, 2019, 11:05:05 pm »
Nah, the problem is far more simple - they are watching 'important' and 'the_rest' in the test bench,, but not passing it into the prallel_comp_inst:

Here's the module definition (reformatted):
Code: [Select]
module parallel_comp(
   important,
   the_rest,
   pin_1,
   pin_2,
   data_clk,
   important_compare,
   the_rest_compare,spi_reset
);

But where it is used, "important" and "the_rest" are not mapped (reformatted):

Code: [Select]
parallel_comp parallel_comp_inst(
          .data_clk(data_clk),
          .important_compare(important_compare),
          .the_rest_compare(the_rest_compare),
          .pin_1(pin_1),
          .pin_2(pin_2)
);

If they were to look at "important" inside the module, rather than in the test bench, it will be undefined.

Got to love Verilog :D
« Last Edit: November 26, 2019, 11:06:56 pm by hamster_nz »
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline Bassman59

  • Super Contributor
  • ***
  • Posts: 2501
  • Country: us
  • Yes, I do this for a living
Re: My first FPGA code
« Reply #117 on: November 26, 2019, 11:13:55 pm »
It seems to get out of hand when you design a 2 process state machine with 100+ states in the combinatorial process.  The sensitivity list can get lengthy but the only way to keep the synthesizer from nagging is to add every right-hand-side signal.
The usual advice here is "don't write two-process state machines (unless you have a really good reason to do so, and even then think about it some more)." Forgetting to assign to each left-hand-side in each state results in latches. The process(all) construct lets you not worry about the sensitivity list but you still have to make sure that you assign everything in every state.

Quote
And, on a different matter, provide a default value for every left-hand-side signal.  This is where I have had the most problems.  The state machine hangs because there is no value for a signal even though the next-state is clearly defined.  Basically, I came up with the idea that 'if it doesn't work, look for missing default values first!'.  This is another place where it is easy to mess up when adding additional logic and output signals.
I'm afraid this is both a tools problem and a device problem. VHDL allows you to write initializers for every signal in your design when those signals are declared. (My Verilog is out-of-date; I assume it has a similar mechanism.) In simulation, it's obvious what happens to those signals.

But what happens when the synthesizer gets ahold of them? That all depends.

Recall in VHDL the usual initializer:
Code: [Select]
signal foo : std_logic := '1';
For example, the Xilinx synthesizer (even in ISE, now still in Vivido) will take the initializer and use it to reset or preset each flip-flop in the design at configuration time. Xilinx recommends never using an asynchronous reset in designs using their devices, so this guarantees that your flip-flops will have a reasonable value immediately after configuration, before any synchronous reset you might use. (What we do here is to use a reset supervisor chip to drive the FPGA's PROGRAM input; release of PROGRAM starts configuration and will basically be a chip-wide reset.)

Do other tools and devices support using initializers in this manner? Well, the Actel/MicroSemi devices do not. These devices require an explicit reset to get the to your desired default state. That is, at configuration (these parts have flash-based configuration so that's immediately after power-up) the flip-flops have an unknown state which is not controlled by the VHDL initializer. And worse, at least with the Pro-ASIC3 devices, the flip-flops do not inherently support a synchronous reset (if you code one, you'll get a mux in front of your flip-flip with one side set to the reset/preset value and the other comes from the logic going into it). So you need to provide an external asynchronous reset (which should should synchronize and use that to drive the flip-flops's async reset input) to get everything ready.

So at least in the Actel case, you can't use initializers.

But in that case, since the design requires an async reset, the test bench should provide one. It doesn't have to be very long, either. This will solve your simulation's "lack of initializer" problem, assuming that all signals that require a reset get one.

As to what Intel wants, it's been awhile since I used one of their parts.
 

Offline lawrence11Topic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 322
  • Country: ca
Re: My first FPGA code
« Reply #118 on: November 26, 2019, 11:30:22 pm »
 :'(
 

Offline lawrence11Topic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 322
  • Country: ca
Re: My first FPGA code
« Reply #119 on: November 26, 2019, 11:42:59 pm »
Verilog:  When in doubt, instantiate everything like a headless chicken.

Even tho its completly unnecessary for the tb instantiation to know what is important since it is defined as wire and testbench has no direct write authority.

Its none of its business whats important is, what it should be doing is concentrating on pin_1 like I asked it to.
« Last Edit: November 26, 2019, 11:45:48 pm by lawrence11 »
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9932
  • Country: us
Re: My first FPGA code
« Reply #120 on: November 26, 2019, 11:43:57 pm »
I wasn't thinking about the 'initial' value but rather a default value assigned inside the process, just ahead of the case statement, that provided a value for the named signal in every state unless over-ridden in the state.  Given, say, 50 output signals from the FSM, it would be silly to define them in each of 100 states yet all signals must be defined in all states, one way or another.  Missing one of these signals results in a latch, something to be avoided.

I didn't know that initializers weren't universal.  After all, it is just a configuration bit among millions of other bits configuring the fabric.  Most of my work has been with Xilinx going back to the Spartan 2 and ISE.  Today I was reminded just how good Vivado was when I installed Lattice ICEcube2.  I'm thinking about a lengthy tutorial program that uses the ICEstick evaluation board so I'll have to go with the flow.  Part of the goal is to understand simulation and the course wants to use ModelSim and ICEcube2.  I suppose I could just translate the work to Vivado right off the bat but the results won't identically match the course material.  Maybe I'm still undecided...

The asynchronous versus synchronous reset issue has been debated since the first FPGA project.  I have used mostly asynchronous but if Xilinx says to use synchronous, that's fine.  I have done it wrong for a long time but there's still time to learn to do it right.  I guess the asynchronous approach came from the 7474 which has asynchronous set and reset.


 

Offline emece67

  • Frequent Contributor
  • **
  • !
  • Posts: 614
  • Country: 00
Re: My first FPGA code
« Reply #121 on: November 27, 2019, 04:20:49 pm »
.
« Last Edit: August 19, 2022, 02:37:11 pm by emece67 »
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9932
  • Country: us
Re: My first FPGA code
« Reply #122 on: November 27, 2019, 05:18:01 pm »
I have been thinking about the difference in a single process model and a two process model FSM and it seems to me that I lose 1 cycle due to latency with the single process model.

Suppose I just this instant entered a state A in a two process model and with some combinatorial logic, I produce a SEL signal for a MUX outside the FSM.  I want the MUX to use the duration of state A to select the proper input such that at the very next clock, the output is registered (potentially somewhere else).  If I'm not allowed to output combinarorial logic in a single clocked process, it would seem to me that I need to wait until the following state to use the outputs of the MUX.

Is there a way around this latency issue?

I'll concede that the single process model is faster because I have two chunks of combinatorial logic that need to be resolved in a single clock cycle but, so far, I haven't run up against a timing issue.  Unless the clocked version is twice as fast (and it could be), I don't make up for the time lost due to latency.

An example of a clocked MUX might be a program counter.  It would have 4 operations (PC_NOP, PC_RESET, PC_LOAD and PC_INCREMENT).  The default value in the FSM would be PC_NOP.  Just after an instruction fetch, the FSM would send the code for PC_INCREMENT and if we're going to do a branch, the code would be PC_LOAD and the parallel inputs would come from some permutation of the instruction or, perhaps, some register.  It seems important to me not to add 1 clock of latency because I may need the PC in the next cycle (eg branch).
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9932
  • Country: us
Re: My first FPGA code
« Reply #123 on: November 27, 2019, 05:25:52 pm »

Give different circuits for:
  • always, always @*, always @(clk), always @(rst, clk): all give the same combinational circuit not using clk, in the last two cases reporting warnings about signals not in the list and unused signals
  • always @(posedge clk): gives a FF with a synchronous reset
  • always @(negedge rst, posedge clk): gives a FF with an asynchronous reset
  • always @(negedge rst): gives a FF with a synchronous reset whose clock is also rst, with warnings about data used as clock
  • always @(rst, posedge clk): is reported as non-synthesizable

One of the best things a newcomer can do is model different blocks, synthesize and review the hardware schematic.  What code results in what hardware?  I have a book on HDL design that spends a lot of time on the different ways to model various blocks.  It's very interesting stuff.

I don't know what anyone would expect from PC <= PC + 1; but it isn't some kind of counter.  No, Vivado will use a full-adder in the feedback path and just add 1.  Now, among the hundreds of options, I suppose there is a way to change that but, by default, Vivado uses an adder.  Somehow I think it is important to know that.  Later on I'll figure out why it's important...
« Last Edit: November 27, 2019, 05:34:51 pm by rstofer »
 

Offline emece67

  • Frequent Contributor
  • **
  • !
  • Posts: 614
  • Country: 00
Re: My first FPGA code
« Reply #124 on: November 27, 2019, 06:54:09 pm »
.
« Last Edit: August 19, 2022, 05:54:11 pm by emece67 »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf