Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
Schmerm
Sep 1, 2000
College Slice
CompEng PhD student checking in here. I think I might start on a project to add SystemVerilog support to the open source VTR (Verilog-to-Routing) toolchain. Yay! I may need to implement some new CAD algorithms, and want to push some of my own SV designs through it as benchmarks, without having to dumb down and convert it all to Verilog 1995 (the port naming syntax is so goddamn arcane...ugh)

Adbot
ADBOT LOVES YOU

Schmerm
Sep 1, 2000
College Slice

NevilleBamshoe posted:

Question for the FPGA guys. How many of you make use of dynamic timing analysis in your designs (post fitting timing simulations)? Or do you mostly get away with only static analysis? I'm referring specifically to designs with multiple time domains.

Speaking as an Altera user, I trust the synchronization primitives (the dcfifo and the altera standard synchronizer whose name I forget) for moving data between clock domains safely. Then, only static timing analysis post-fitting is needed. The STA tool also does metastability analysis and it usually gives MTBFs in the billions of years.

Schmerm
Sep 1, 2000
College Slice

Delta-Wye posted:

Best practices for synthesis question:

I have a statemachine that walks through states doing it's thing. This is great, but one of the states needs to do the same thing for 8 clocks. The Xilinx example Moore statemachine relies on three processes for running, a single process that assigns state <= next_state, a process that changes outputs based on the current value of state, and another process that determines the next_state from the current state plus inputs. This is great, but I'm not sure the easiest and cleanest way to get it to stay in a single state for a number of clocks (effectively for a certain amount of time). I have a few ways to do this in simulation, but I'm not sure which solution is more common and easier for the synthesis tool to make sense of.

1: Create a hardware counter. I did this with a shift register - when you enter the state, it starts shifting '1', and when the '1' pops out the other side, transitions. The implementation is in a separate vhdl file and is literally a std_logic_vector whose length is set as a generic parameter. This works, but seems like it ties the synthesis tools hands a bit by being specific.

2: Use a variable to control timing. The process for determining next state has a synchronous section that increments the variable and once it hits a certain amount, moves to the next state. I am hesitant to use variables because I do not have a good feeling for what hardware they turn into, but this is a pretty clean way to do it code-wise.

3: Add additional states. This seems kind of grotesque but I could simply have a bunch of states do_work_0 through do_work_7 instead of trying to sit in state do_work for 8 clocks. No counting necessary, it just walks through the states. However, I have a state machine with 12 states already, and this would balloon it up to 40 or so.

4: Additional state machine. I could build another state machine that just walks through eight states and use its outputs to control the main state machine. Seems similar to #2 in every way but implementation, to be honest. And if you have one-hot encoding, I suspect it will look very similar post synthesis.

I'm getting comfortable with VHDL, but I still have a huge black hole in my library of "design patterns" and I am still uncomfortable with the synthesis tool; I write code that will pass simulation no problem but I don't have a intuitive sense of what happens when I pass it down the toolchain.

I am one big case of analysis paralysis :downs:


Ew, VHDL. Aside from that, option 1 is essentially what I use whenever this needs to be done. Don't do #2 because it might break the synthesis tool's recognition of the state machine, since the logic will no longer be an unconditional "every clock, copy nextstate to state". 3 and 4 are identical but messy. #1, if done using a one-hot counter (= shift register) will be just as efficient as whatever state machines get synthesized as these days.

Schmerm
Sep 1, 2000
College Slice

Rescue Toaster posted:

So can someone sensibly explain why I need to declare the output of a multiplexer or the like as a reg even though both I and the compiler know the resulting logic will not be registered? Obviously it's because you're using an always block. But if I use all blocking assignments and ensure that the output is defined in all 'execution paths' then there won't be a register created.

It seems like it would make more sense to let me declare the output as a wire, and then have the compiler generate an error if I didn't meet the requirements of it being purely combinatorial. That way at least I know what's happening and if I messed up. As is it just silently gets turned into a real register, I guess?

The left hand side of any assignment in an always block must be a 'reg', which you already said. If it's a combinational always block, it will generate a wire. If it's a clocked always block, it will generate a register. That's it. Blocking/nonblocking/executionpaths discussion is irrelevant, except for creating latches. Latches are bad and we don't talk about them in FPGA Land.

Switch to SystemVerilog if you can. There's a datatype called 'logic' that's usable in both always blocks and with assign statements, and can replace 'reg' and 'wire' for 99% of cases. There's also 'always_ff' and 'always_comb' blocks. The former ensures that you create nothing but registers (and errors will be generated if your flow creates latches). The latter is a nice syntactic replacement for 'always @*'

Schmerm
Sep 1, 2000
College Slice
Verilog has had generate statements since Verilog-2001, and sensitivity lists are deprecated for anything other than maybe speeding up simulations.

Schmerm
Sep 1, 2000
College Slice
Jesus guys, that sounds bad. Just go Altera already... synthesis works, and you get SystemVerilog support for all families, not just newer ones like with Xilinx.

Here's my conventions I use in (System)Verilog:

  • All names lowercase
  • Module inputs and outputs: i_inputname, o_outputname
  • Exception to above, for topmost pins connecting to outside the FPGA, are all uppercase
  • Clocks, especially: clk if there's one, or clk_300 for a/The 300MHz clock, clk_ddr for the memory clock, etc
  • Active-low signals: suffix of _n
  • States: Defined using 'localparam' in V2001, 'enum int unsigned' in SV, named S_IDLE, S_KILL_ALL_HUMANS, etc
  • Control signals for a register 'foo' that is meant for holding things:
    • foo_load - loading from a hardwired or selectable input
    • foo_din - the input to load from, if applicable
  • Control signals for a register 'foo' used as a counter:
    • foo_inc - increment
    • foo_dec - decrement
    • foo_last - combinational signal to show that foo has reached its last value this cycle. Usually written as "wire foo_last = foo == 99" or "wire foo_last = foo == 0"
    • foo_done - same as above, but for one-past-the-end semantics (like C-style for loops). "wire foo_done = foo == 100"
  • Pipeline registers: foo_0, foo_1, etc for stage 0, stage 1, etc.
  • Handshaking signals: valid/ready. Usually they're ports, so there is an i_valid, o_ready pair for receiving, and a o_valid, i_ready pair for sending

Adbot
ADBOT LOVES YOU

Schmerm
Sep 1, 2000
College Slice
Could you simply infer a ROM from VHDL/Verilog? Both Xilinx and Altera support this for synthesis, and you can use the $readmemh Verilog system function to initialize the ROM contents from a file.

Altera: http://www.altera.com/literature/hb/qts/qts_qii51007.pdf p38
Xilinx XST (probably works in Vivado too): http://www.xilinx.com/support/documentation/sw_manuals/xilinx13_1/xst.pdf p192

  • Locked thread