Author Topic: Resources for learning FPGA  (Read 9336 times)

0 Members and 1 Guest are viewing this topic.

Offline Yansi

  • Super Contributor
  • ***
  • Posts: 3893
  • Country: 00
  • STM32, STM8, AVR, 8051
Re: Resources for learning FPGA
« Reply #25 on: February 07, 2020, 02:18:09 pm »
That is probably the incorrect programmers thinking model.

It defaulting to 32bits is likely just your incorrect assumption.  HDL does not work with bytes.
 

Offline aheidTopic starter

  • Regular Contributor
  • *
  • Posts: 245
  • Country: no
Re: Resources for learning FPGA
« Reply #26 on: February 07, 2020, 02:23:40 pm »
That is probably the incorrect programmers thinking model.

It defaulting to 32bits is likely just your incorrect assumption.  HDL does not work with bytes.

Not really:

Code: [Select]
count <= (count + 1) ;
gives me the following output: "WARNING - top.v(42): expression size 32 truncated to fit in target size 24. VERI-1209 [top.v:42]

See the code in my previous post for context.
 

Offline emece67

  • Frequent Contributor
  • **
  • !
  • Posts: 614
  • Country: 00
Re: Resources for learning FPGA
« Reply #27 on: February 07, 2020, 02:27:37 pm »
.
« Last Edit: August 19, 2022, 03:50:48 pm by emece67 »
 

Offline Yansi

  • Super Contributor
  • ***
  • Posts: 3893
  • Country: 00
  • STM32, STM8, AVR, 8051
Re: Resources for learning FPGA
« Reply #28 on: February 07, 2020, 03:05:34 pm »
That is probably the incorrect programmers thinking model.

It defaulting to 32bits is likely just your incorrect assumption.  HDL does not work with bytes.

Not really:

Code: [Select]
count <= (count + 1) ;
gives me the following output: "WARNING - top.v(42): expression size 32 truncated to fit in target size 24. VERI-1209 [top.v:42]

See the code in my previous post for context.

HDL has nothing to do with bytes. It has zero reasons to default to any multiples of 8 bits other than you have defined the other signal or set of flip flops to be 32 bits wide.

Maybe it is just me, because I am no Verilog guy, I can understand only VHDL.

 

Offline aheidTopic starter

  • Regular Contributor
  • *
  • Posts: 245
  • Country: no
Re: Resources for learning FPGA
« Reply #29 on: February 07, 2020, 03:30:07 pm »
HDL has nothing to do with bytes.
This is crystal clear.

It has zero reasons to default to any multiples of 8 bits other than you have defined the other signal or set of flip flops to be 32 bits wide.

Right, but clearly the tool I'm using generates a 32bit adder when I'm using the + operator. I did not expect this since I declared the "register" as 24 bits, but ok, similar widening happens in C too and is nice if you want the extra carry bit. My confusion stems from not being able to discard the output from the upper 8 bits via a simple [23:0] at the end.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 15246
  • Country: fr
Re: Resources for learning FPGA
« Reply #30 on: February 07, 2020, 03:34:57 pm »
That is probably the incorrect programmers thinking model.

It defaulting to 32bits is likely just your incorrect assumption.  HDL does not work with bytes.

Not really:

Code: [Select]
count <= (count + 1) ;
gives me the following output: "WARNING - top.v(42): expression size 32 truncated to fit in target size 24. VERI-1209 [top.v:42]

See the code in my previous post for context.

I don't know Verilog much - VHDL here too - but from the above, I'm assuming that Verilog in that respect is kind of similar to C as to how it handles arithmetic expressions.

Looks like 'count + 1' is not the same type as 'count', but probably the same type as '1', which is likely to be of some integer type, making the whole expression 'count + 1' effectively an integer. Then it is implictly cast back to the type of 'count' with the assignment, and the warning is thus correct.

If, instead of "1", you use "24'b1" (I think this is the correct syntax?), I guess the warning should go away? Like: "count + 24'b1".

This just shows that Verilog does more of implicit "casts" (like C does in a way), whereas VHDL in general does not. But with the example above, it's a bit trickier than this.
If you're using an 'unsigned' type for 'count' in VHDL, for instance, you can absolutely write "count <= count + 1" without any warning. This is because the '+' operator is redefined for unsigned types, and in this context, the '1' litteral is not seen as an integer.

As to why 32 bits, it's consistent with what I said above. It's just because the expression implicitly becomes an integer, and integers are likely 32 bits by default in Verilog, just like they are in VHDL (but using integers in VHDL would require explicit casts).
 

Offline aheidTopic starter

  • Regular Contributor
  • *
  • Posts: 245
  • Country: no
Re: Resources for learning FPGA
« Reply #31 on: February 07, 2020, 03:40:34 pm »
Looks like 'count + 1' is not the same type as 'count', but probably the same type as '1', which is likely to be of some integer type, making the whole expression 'count + 1' effectively an integer. Then it is implictly cast back to the type of 'count' with the assignment, and the warning is thus correct.

If, instead of "1", you use "24'b1" (I think this is the correct syntax?), I guess the warning should go away? Like: "count + 24'b1".

Good call, that seems to be it. I should add that the "count <= (count + 1)" line was not written by me, but came with the Radiant skeleton example I used as base.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 15246
  • Country: fr
Re: Resources for learning FPGA
« Reply #32 on: February 07, 2020, 03:48:32 pm »
Looks like 'count + 1' is not the same type as 'count', but probably the same type as '1', which is likely to be of some integer type, making the whole expression 'count + 1' effectively an integer. Then it is implictly cast back to the type of 'count' with the assignment, and the warning is thus correct.

If, instead of "1", you use "24'b1" (I think this is the correct syntax?), I guess the warning should go away? Like: "count + 24'b1".

Good call, that seems to be it. I should add that the "count <= (count + 1)" line was not written by me, but came with the Radiant skeleton example I used as base.

Good. I think this would qualify as "sloppy Verilog", even though that compiles right (but with a warning) and does what is intended here.
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9931
  • Country: us
Re: Resources for learning FPGA
« Reply #33 on: February 07, 2020, 04:07:30 pm »
When you draw out your block diagram, physically, not just mentally, every time you use 'reg', draw a flip-flop.  What's connected to D, where is the Clk coming from, is reset synchronous or asynchronous?  The compiler didn't like the way you tried to connect a flop to another flop without clocking the second flop.  Between modules, I'm pretty sure you can only use wires.  Again, I know next to nothing about Verilog.

I can't offer any advice about Verilog and this wire/reg issue is one of the reasons I find it difficult to wrap my head around what is happening.  Again, that's just me.

See section 1.2 here:  https://inst.eecs.berkeley.edu/~eecs151/fa19/files/verilog/wire_vs_reg.pdf
Section 1.3 deals with regs

There are very specific rules for where wires can/must be used and similar rules for regs.

There's a trap in copying code off the Internet in that snippets are unlikely to work without the identical foundation.

I like the VHDL 'alias' construct for pulling subfields out of a standard logic vector.  Think about the Instruction Register and how source (SR1, SR2) and destination (DR) fields would be  in certain bit positions.

Code: [Select]
    signal  IR              : std_logic_vector(15 downto 0);
    alias   Immediate       : std_logic is IR(5);
    alias   DR              : std_logic_vector is IR(11 downto 9);
    alias   SR1             : std_logic_vector(2 downto 0) is IR(8 downto 6);
    alias   SR2             : std_logic_vector(2 downto 0) is IR(2 downto 0);
[/font]

To me, that is a clean way to name various fields
« Last Edit: February 07, 2020, 04:31:32 pm by rstofer »
 
The following users thanked this post: aheid

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9931
  • Country: us
Re: Resources for learning FPGA
« Reply #34 on: February 07, 2020, 04:27:36 pm »
Looks like 'count + 1' is not the same type as 'count', but probably the same type as '1', which is likely to be of some integer type, making the whole expression 'count + 1' effectively an integer. Then it is implictly cast back to the type of 'count' with the assignment, and the warning is thus correct.

If, instead of "1", you use "24'b1" (I think this is the correct syntax?), I guess the warning should go away? Like: "count + 24'b1".

Good call, that seems to be it. I should add that the "count <= (count + 1)" line was not written by me, but came with the Radiant skeleton example I used as base.

Good. I think this would qualify as "sloppy Verilog", even though that compiles right (but with a warning) and does what is intended here.

I agree, the code seems a little off.  In Verilog, especially, I think there is a simpler construction trying desperately to get out.

Verilog can absolutely create a 24 bit counter without remnants of 32 bit addition but I think that is settled.  Apparently the increment value needs to be specified as a 24 bit value = 24'b1.  This makes sense in a way because in VHDL, if I am dealing with a std_logic_vector, I have to do a lot of casting to add '1'.  Mainly, the operands need to be numbers - signed or unsigned - but numbers, not a std_logic_vector.


Code: [Select]
PCplusOne <= std_logic_vector(unsigned(PC) + 1);
[/font]

Here, both PC and PCplusOne are declared as std_logic_vector(15 downto 0).  To add decimal 1 to a standard logic vector, I first have to convert the signal to an unssigned then do the math and convert the result back to std_logic_vector before assigning it to PCplusOne.  Like C casting in a lot of ways...

OK, I used to think this was UGLY and there was an unofficial library that would let me do that kind of addition without casting but, as I get used to it, I find it comforting.  The compiler still generates a 16 bit adder with PC and decimal 1 as inputs but it is very clear exactly what the programmer expected.  I'm getting to like it!

STRONG typing is a benefit, not a hindrance.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 15246
  • Country: fr
Re: Resources for learning FPGA
« Reply #35 on: February 07, 2020, 05:30:08 pm »
Code: [Select]
PCplusOne <= std_logic_vector(unsigned(PC) + 1);

Yes, and I know it's just an illustration. But in this form, it probably just looks too verbose to many.
To avoid this incessant casting all over the place, you just define internal signals with the proper type, and cast only when strictly needed.

In your example, I'd have an internal PC and PCplusOne signals declared as 'unsigned'.
"PCplusOne <= PC + 1;" would be all that's needed, it's compact and besides, it helps making things clearer and convey the intent, in other words, it really leverages the typing system.

Then you only cast to std_logic_vector to interface with external ports, so basically just in one place.

I almost never use the std_logic_vector type internally in my entities, except for signals that are really to be handled just as zero or one. And even so, I tend to use the boolean type instead, and cast again only from/to external ports in just one place.

Just makes your code a lot more compact and easier to maintain, with exactly zero cost.

STRONG typing is a benefit, not a hindrance.

Oh yes.
 
The following users thanked this post: aheid

Online RoGeorge

  • Super Contributor
  • ***
  • Posts: 6688
  • Country: ro
Re: Resources for learning FPGA
« Reply #36 on: February 07, 2020, 05:36:47 pm »
Well say I got 32 outputs from a bunch of ICs sitting on a breadboard. I want to feed these to a new set of ICs on another breadboard. Why can't I just hook up the 24 wires for the first 24 ouputs, and ignore the last 8 outputs? Alternatively, if I got a 32bit adder as one big IC, why can't I simply ignore the pins representing the upper 8 bits? What's wrong with that?

Nothing wrong.  But then you need to increment the whole 32 bits counter, and wire to the next circuit only the 24 bits you need.  Seems very similar to a typecast, but it's not about changing a data type, it's about rewiring a circuit.



Please put the code of the whole module, so we can discuss it line by line, and make an idea of what is happening under the hood. 

The module I copied from some sample code, I just modified the name of it and the text file it reads the data from:
Code: [Select]
module ROM_SIN_256(
    input clk,
    input [7:0] addr,
    output reg [7:0] dout
);
    reg [7:0] memory [0:255];

    initial
        $readmemh("sin_256.txt", memory);
   
    // synchronous ROM
    always @(posedge clk)
        dout <= memory[addr];
       
endmodule

In my top.v file I have this:
Quote
reg sin_clk;
reg [7:0] sin_addr;
reg [7:0] sin_val;

always @ (posedge oclk)
   /* other code */

   ROM_SIN_256 sin_inst(
      .clk(sin_clk),
      .addr(sin_addr),
      .dout(sin_val)
   );

This leads to: "ERROR - concurrent assignment to a non-net sin_val is not permitted. VERI-1195 [top.v:78]".

If I change the declaration of "sin_val" to
Code: [Select]
wire [7:0] sin_val; I don't get an error. What confused me was that dout is declared as "reg", and since I've not yet studied modules in depth I just have an implicit understanding of the syntax. But I think that has more to do with how Verilog works than how the hardware works.

Let's focus only on the registers that gives the error.  The toolchain will see in the top.v file you described some registers.  A register is built out of D-type flip-flops.  A D-type flip-flop is a circuit that, on the rising edge of the clock signal, it copies at the Q outputs what the data present at the D input.  Once copied, the flip-flop will memorise the data, and doesn't look at the D input any more until the next rising edge, when it will copy D to Q again, and so on.

The typical D-type flip-flop has some more pins, S and R for (asynchronous) set or reset, non Q, as can be seen in the next hand drawing, or in this (random googled) datasheet in figure 3: https://assets.nexperia.com/documents/data-sheet/74HC_HCT74.pdf where there are 2 flip-flops in the same case of an IC.

An 8 bit register will be made out of 8 D-type flip-flops (FF), where the clock and the reset inputs are usually connected together.  To stay with the breadboard you mentioned, an 8 bit register will be 4 x 7474 ICs, each with 2 flip flops inside AND THE WIRES necessary to build the circuit from the right side of the picture:



Now, let's get back to the FPGA toolchain.
- at some point toolchain reads the line "reg [7:0] sin_val;", take 4 x 7474ICs and insert them in our breadboard
- it continues reading, do some other stuff, and at some points it reads
Code: [Select]
ROM_SIN_256 sin_inst(
.clk(sin_clk),
.addr(sin_addr),
.dout(sin_val)
);

This is very close to what a macro does for the preprocessor of the C language, but I will be afraid to call it a macro.  On short, the toolchain will look in the module file, and start to generate the circuits described in the module.  One of the lines inside the module ROM_SIN_256 is "output reg [7:0] dout".  This will synthesise yet another 8 bits register.

For our breadboard, the toolchain inserts another 4 IC (meaning another 8 flip-flops).  At this point, we have 16 flip flops in 2 x 8 bit registers, one is "sin_val", the other "dout".  At this point, the toolchain is left with 3 busses of 8 bits each, databus Z", "databus X", and "databus Y", as seen in the next pic, and doesn't know how to wire them.



My guess is that you probably didn't want yet another register in main.v, the one you created with "reg [7:0] sin_val;".

However, if you wanted it, then you need to instruct the toolchain how to wire it to the outputs of the "dout" register, and keep in mind the sin_val will be filled with data one clock later than dout (assuming they are driven by the same clock).



My point is, in the very beginning, it is very misleading to think of all these as typecasts or macros, or even worst, class instantiation of an object, when in fact we deal here with circuits, wires and clocks.

Very soon you'll get use to it, and you'll naturally start to mix software and hardware design techniques, but for now keep thinking about HDL in terms of circuits.
 
The following users thanked this post: aheid

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9931
  • Country: us
Re: Resources for learning FPGA
« Reply #37 on: February 07, 2020, 06:19:50 pm »
Code: [Select]
PCplusOne <= std_logic_vector(unsigned(PC) + 1);

Yes, and I know it's just an illustration.
Not really, I actually coded it that way on purpose.
Quote
But in this form, it probably just looks too verbose to many.
I can certainly agree with that but I can type pretty fast when I get down to it.
Quote
To avoid this incessant casting all over the place, you just define internal signals with the proper type, and cast only when strictly needed.

In your example, I'd have an internal PC and PCplusOne signals declared as 'unsigned'.
"PCplusOne <= PC + 1;" would be all that's needed, it's compact and besides, it helps making things clearer and convey the intent, in other words, it really leverages the typing system.

Then you only cast to std_logic_vector to interface with external ports, so basically just in one place.


I agree, unsigneed is the way to go but either way, I need to cast signals from one type to another.  That's a practice I haven't quite caught on to.  When I create a new entity and I use the 'fill-in-the-blanks' creator in Vivado (and ISE), if I declare the signals in the dialog they will always come out as std_logic_vector.

Either way, I need to know what type I'm using and why I'm using that type.  And I need to know which operators accept the various types.  And, yes, unsigned is the right way to do it.

 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9931
  • Country: us
Re: Resources for learning FPGA
« Reply #38 on: February 07, 2020, 06:54:09 pm »
Maybe the reason I don't often use unsigned instead of std_logic_vector is the way I think about the hardware.  I realize the program counter is an index into memory but that isn't the way I view it.  Instead, I think of it as a 16 bit vector with LEDs attached.  Nothing numeric about it, it's just a string of bits.

A better example might be the accumulator.  Sure, it does numeric add and subtract and could be defined as unsigned but it also does AND and OR which are clearly bit-vector operations.  I'm not sure what to think about shift because it has meaning in numbers as well as vectors.

I think this is why employers have 'style manuals'.  They make a decision about this stuff and it's over and done.  My indecision is overridden by corporate edict. If I wasn't long retired...

I think I'm going to stick with std_logic_vector despite all the reasons to do otherwise.  Old people can write their own style manual.

I actually used an integer type for the current and next state values on the LC3 FSM.  I wanted the state number to match the state diagram.  It looks  a little weird but it works fine.

Code: [Select]
signal State            : integer range 0 to 63;
signal NextState        : integer range 0 to 63;
[/font]
I still had to cast State to a std_logic_vector to include it as part of a wider diagnostic output to the LEDs.  But only the one time.
« Last Edit: February 07, 2020, 07:01:51 pm by rstofer »
 

Offline aheidTopic starter

  • Regular Contributor
  • *
  • Posts: 245
  • Country: no
Re: Resources for learning FPGA
« Reply #39 on: February 08, 2020, 12:43:19 am »
Thanks again for the input and discussion. I've gotten some solid suggestions on reading material, and cleared up some syntax confusion.

Got my led to pulse with nice sin wave intensity using my own PWM module, yay. Time to do some serious reading before trying something more complex :)
« Last Edit: February 08, 2020, 12:49:56 am by aheid »
 

Offline james_s

  • Super Contributor
  • ***
  • Posts: 21611
  • Country: us
Re: Resources for learning FPGA
« Reply #40 on: February 08, 2020, 03:11:56 am »
PS  folks piling on to say how you need to get out of the programming mindset, and remember that you are wiring circuits, is almost cliche in these threads.  It is true, but most new students figure that out pretty quick.  For me, the hardest part of "getting past blinky" is all of the stuff they *don't* cover in a text on VHDL/Verilog for synthesis.  How to write constraints, how to know when to instantiate vendor-specific blocks vs trusting the synthesizer to do it for you, how to decompose complex tasks---especially DSP stuff.

And yet almost every self taught HDL beginner who has previous programming language starts trying to code HDL as if it's a program being executed, and it's also the aspect that I found most difficult early on, so cliche or not I tend to mention it.
 

Offline OwO

  • Super Contributor
  • ***
  • Posts: 1250
  • Country: cn
  • RF Engineer.
Re: Resources for learning FPGA
« Reply #41 on: February 08, 2020, 06:59:33 am »
Yes, before writing any HDL you should have a drawing of the circuit being designed. HDL is often called "design entry" for a reason, as in you are only "entering" into the computer a circuit that is already designed. The diagram is the "master design" while the HDL is only a copy of it, therefore when making changes always do it on the diagram first. In the future when you need to look at your design again, code is much harder to read and reason about than having a well documented diagram of the system that shows you the big picture at once.

If you ever learn VHDL, ignore 90% of example code out there. Avoid using "process" except when trying to infer a block ram. Everything should be done as a "signal flow graph" model. You define your signals, then you define drivers for each signal. Example:

Email: OwOwOwOwO123@outlook.com
 
The following users thanked this post: aheid, emece67

Offline OwO

  • Super Contributor
  • ***
  • Posts: 1250
  • Country: cn
  • RF Engineer.
Re: Resources for learning FPGA
« Reply #42 on: February 08, 2020, 07:04:08 am »
The associated diagram of the above design:

923872-0
Email: OwOwOwOwO123@outlook.com
 

Offline ali_asadzadeh

  • Super Contributor
  • ***
  • Posts: 1929
  • Country: ca
Re: Resources for learning FPGA
« Reply #43 on: February 08, 2020, 07:19:16 am »
Quote
If you ever learn VHDL, ignore 90% of example code out there. Avoid using "process" except when trying to infer a block ram. Everything should be done as a "signal flow graph" model. You define your signals, then you define drivers for each signal. Example:
Nice tips, Do you have a book  or reference for this?
ASiDesigner, Stands for Application specific intelligent devices
I'm a Digital Expert from 8-bits to 64-bits
 

Offline OwO

  • Super Contributor
  • ***
  • Posts: 1250
  • Country: cn
  • RF Engineer.
Re: Resources for learning FPGA
« Reply #44 on: February 08, 2020, 07:49:07 am »
Nah, it's the style taught by a professor at my university.

Also btw it's not about "low level" design - I avoid bit level manipulations and use high level types when possible; for example complex value types, library functions for math, etc.

However the structure and layout of the circuit - this is what I think must be explicitly spelled out. I want to be sure exactly what each flipflop is driven by, any clock enables used, where all MUXs are, etc.
An example of code I don't like:
Code: [Select]
if rising_edge(clk) then
  if alumode = 0 then
    res <= a + b;
  elsif alumode = 1 then
    res <= a - b;
  elsif alumode = 5 then
    res <= a xor b;
  elsif alumode = 6 then
    res <= a and b;
  else
    if addr != X"ffffff" then
      res <= 0;
    end if;
  end if;
end if;
What circuit is this going to actually infer?
  • Most FPGA adders support dynamic add/subtract selection. Is that going to be inferred here or is it going to be a 5:1 MUX?
  • It's not obvious from the code, but res is going to be driven by logic that traverses at least 2 stages of slices in a Xilinx device (adder, then mux). This ruins your Fmax.
  • Can you see the high fan-in clock enable logic?
If this is a long process, I have to read the whole thing and look for every instance of assignment to "res", look at all conditionals, and track duplicate assignments to know what res is actually driven by. Instead, something like:
Code: [Select]
resNext <= XXXXX when CONDITION else
                  YYYYY when CONDITION ......
res <= resNext when CONDITION and rising_edge(clk);

is far easier to understand.

A slow and unoptimized design like the above is still viable with the "process" approach, but what do you do when you want to add pipelining? You kind of have to guess at the structure of the circuit. It's much easier when that is explicit from the start.
« Last Edit: February 08, 2020, 07:53:12 am by OwO »
Email: OwOwOwOwO123@outlook.com
 
The following users thanked this post: aheid

Offline sporadic

  • Regular Contributor
  • *
  • Posts: 72
  • Country: us
    • forkineye.com
Re: Resources for learning FPGA
« Reply #45 on: February 09, 2020, 03:44:52 pm »
The associated diagram of the above design:

(Attachment Link)

Any software recommendations for creating and managing state diagrams?
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 15246
  • Country: fr
Re: Resources for learning FPGA
« Reply #46 on: February 09, 2020, 04:20:38 pm »
The associated diagram of the above design:

(Attachment Link)

Any software recommendations for creating and managing state diagrams?

Want something with a GUI or something that can generate diagrams from a textual representation?

For the former, there is DIA (unfortunately not maintained, tends to be clunky to use, but open source). There is XMind. There is yEd Graph Editor (which is the one I currently use the most). Probably a lot more, but those are the ones I use(d).

For the latter, there is graphviz. And of course various Latex packages if you ever use Latex.
 
The following users thanked this post: sporadic

Offline sporadic

  • Regular Contributor
  • *
  • Posts: 72
  • Country: us
    • forkineye.com
Re: Resources for learning FPGA
« Reply #47 on: February 09, 2020, 05:09:44 pm »
The associated diagram of the above design:

(Attachment Link)

Any software recommendations for creating and managing state diagrams?

Want something with a GUI or something that can generate diagrams from a textual representation?

For the former, there is DIA (unfortunately not maintained, tends to be clunky to use, but open source). There is XMind. There is yEd Graph Editor (which is the one I currently use the most). Probably a lot more, but those are the ones I use(d).

For the latter, there is graphviz. And of course various Latex packages if you ever use Latex.

I can't believe I've never run across yEd while looking for diagramming software.  I'd always painfully used DIA in the past. Just watched intro video on yEd and it looks like just what I need. Going to grab it now, thanks!
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9931
  • Country: us
Re: Resources for learning FPGA
« Reply #48 on: February 09, 2020, 05:49:41 pm »
A worthy project is to take some of these constructs, like the FSMs and synthesize them.  Then look at the RTL schematic.  The synthesizer will warn you if you have inferred a latch but what it won't tell you is whether you have inferred a priority encoder and whether that priority encoder is realized as a long string of logic which doesn't help with Fmax.

Here is a comment re: using the 'case' statement rather than a long chain of 'if-elsif-else' statement:
https://www.nandland.com/vhdl/examples/example-case-statement.html

Just for a drill, code a simple FSM with both schemes and look at the RTL schematic.  No, I don't know how it's going to turn out.  I sure wouldn't use the "when" construct for an FSM with 100+ states.  The other problem I have with that approach is that it tends to divorce the actions to be taken in a state from the next-state generation.  I then have to scroll down to see what happens as a result of being in a particular state.  More to the point, there may be several constructs that use the state information and they could span many pages of code.

I think I'm going to stay with the two process state machine, one to clock the next-state and the other combinatorial process to generate the output signals.  I don't know how the big kids do it but I like this approach.


Code: [Select]
    process(State, BEN, IR,MemReady, Immediate, PSR, Interrupt)
    begin
        -- set default values for all signals - many omitted for clarity
        SR2select       <= SR2OutSel;
        GateBusSelect   <= GatePC;
        LD_Reg          <= '0';
        LD_CC           <= '0';
        ALUop           <= ALUpassA;

       case State is
<snip>                         
            when  1     =>  -- ADD Instruction
                            if Immediate = '1' then
                                SR2select <= Sext5sel;
                            else
                                SR2select <= SR2outSel;
                            end if;
                            ALUop           <= ALUadd;
                            GateBusSelect   <= GateALU;
                            LD_Reg          <= '1';
                            LD_CC           <= '1';
                            NextState       <= 18;
<snip>
        end case;
    end process;
[/font]

When the FSM is in state=1, we can see exactly which output signals are generated inside the combinatorial process.  The adder is going to do an add operation, we're going to gate the ALU to the bus and load the result into some register (selected the DR field in the instruction) as well as loading the condition codes prior to fetching the next instruction in state 18.

Everything is in one place and the operations performed in any particular state are right there.

The state info is from the LC3 project I linked above.

 

Offline ralphrmartin

  • Frequent Contributor
  • **
  • Posts: 487
  • Country: gb
    • Me
Re: Resources for learning FPGA
« Reply #49 on: February 09, 2020, 06:05:08 pm »
Going back to the original question, and perhaps not being entirely helpful, as this is VHDL not Verilog, I have just been reading
Digital System Design with VHDL by M. Zwolinski
It's rather old, but it does cover quite a lot of useful and helpful ideas at just the right pace (for me, anyway), covering what VHDL can do and how to use it, key elements used in digital design, and how to put them together.
Unlike many other books which either teach digital design, or teach VHDL, it treats digital design and VHDL hand in hand.
I'd specifically recommend it if you are a software guy getting into FPGAs, for example.
 
The following users thanked this post: Yansi, aheid


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf