开发者

VHDL process style

开发者 https://www.devze.com 2023-01-29 17:09 出处:网络
I have been reading through va开发者_高级运维rious questions on here, as I am learning VHDL and always looking to improve. However, this comment made me curious:

I have been reading through va开发者_高级运维rious questions on here, as I am learning VHDL and always looking to improve. However, this comment made me curious:

Simple State Machine Problem

I was told, in my brief VHDL course at university, that separate processes was best form, to separate the synchronous aspects.

Obviously this is personal preference, but I was hoping that some more experienced users may be able to shed some light on the pros/cons, with their own preferences? Is one more common than the other?

Thanks!


Well, as it was me that said what you've linked to... I'd better comment :)

Bad things (IMHO) if you put things in separate processes:

  • you have to keep your sensitivity list religiously up to date
  • You have to provide defaults for every output, unless you want asynchronous latches (which you usually don't)
  • The logic is split up, so if you add a state to a state machine, you have to put the new state in both processes
  • If you want a signal to be used both registered and unregistered, you end up duplicated it. With a single process you can use variables to achieve this.
  • some people think it's harder to read.

Good things:

  • You can have the "output" of a state unregistered. This can be good for reducing latency, but for almost all purposes you want registers on the output of each block to make meeting timing easier.
  • Some people think it's easier to read

My opinion is that edicts like you heard ("keep it separate") stem from the days when synthesisers weren't very good at differentiating the logic from the flops, so putting just the flops in clocked processes made sense.

Furthermore, that approach matched the way people of that era drew schematic diagrams before they had HDLs.

These days, synthesisers can deal with arbitrarily complex logic in clocked processes. And I can write it the way that makes sense without having to be explicit about where each tiny bit of logic sits. Only when timing is really tight do I have to think really hard about placing flops and logic in just the right places.

My "rules" are:

  • Keep it readable
  • If it meets the requirements (eg power, timing and functions OK), you're done.
  • If not, then and only then play unreadable tricks

A lot like writing software :)


I'm in the keep it separate camp. In my code I have a single synchronous process which does reset and clocking behaviour. Everything else is async. A register process looks something like this:

Wait for Clock;
If Reset then
    Value <= '0';
else
    Value <= nextValue;
endif

Things I like:

  • It's obvious which signals are flops. They are the ones in the clocked process.
  • I write the register process once and forget about it.
  • All your async processes are "pure" functions with no retained state.
  • Forces you to split logic at registers, separating pipeline stages, etc
  • It promotes a style which is many, small, simple, async processes.
  • Due to this logic cones are easier to understand and optimise.
  • Big processes are likely to be the ones that have problems with timing closure. Early alarm bells.

Negatives:

  • Sensitivity lists, but Emacs has a macro for this, and it comes out in warnings. If the list is huge your process is too big.
  • Defaults for every output, but that actually serves as documentation. Right at the start of a process, these are my outputs and defaults. Again, caught by warnings if I get it wrong. It's also far easier to catch a latch (which you almost never want) than a extra flip-flop because and async term wasn't assigned in one path.

Things I don't quite understand from Martin's answer:

  • The logic is split up, so if you add a state to a state machine, you have to put the new state in both processes

I change the type of my state variable (i.e. add an enum) and move on. Exactly the same as in unified style.

  • If you want a signal to be used both registered and unregistered, you end up duplicated it. Witha single process you can use variables to achieve this.

In split style you already have the registered and unregistered versions. They are the input and output to the register process. No extra work at all.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号