Kind on hard-simple question,
i know it's general but that is exactly why i am asking...
if i write a code in vhdl and i use a process which starts this way:
Process(clk,x,y,x)
begin
...
end process
is there any way which in i won't have to save x,y,z values ? the way i understand this, if i wont save them, i wont be able to say if one of them changed which means i have to save them.
im writing assignment with a friend for university and we have different opinions. thanks a lot for helpers !
It totally depends on your needs.
In case you don't know - when you make some project in VHDL for FPGA, CPLD etc. you have to forget about what you knew about programming, because you are designing hardware, not software. You mostly, if not always, you don't have to save this values, for example when you make combinatorial circuit. In this case you don't care what was before, but only what this value is currently. Look at some examples with finite states machines, that has process with combinatorial logic.
And lastly – if you put clock to sensitivity list, it means that you want it to be synchronous, and process will launch only on some edge of this clock, so putting any more signals to it (with exception for reset) is pointless.
Related
I'm trying to write the control logic module for a toy processor. It cycles through the fetch/decode/execute states, reads and writes from various bits of memory, and sets a bunch of control signals. It's somewhat large, and as far as I can tell it can't really be subdivided into smaller modules.
I don't want to put the logic for all of the states into one process -- it's hard to read, and the mass of intermediate aliases & signals are a pain when using the simulator.
I tried splitting each state's logic into its own process, but then I had problems with multiple drivers.
I also tried declaring separate procedures for each state's logic in the head of one main process, and had the process just call the correct procedure based on the current state. This worked quite nicely, with modular "functions" and a more readable structure... but each procedure's intermediate signals aren't visible in the simulator (and maybe not accessible to a testbench? I gave up before trying that.). I was using ISim in case that's relevant.
Was I doing something wrong? Is there some trick I can use to avoid having one massive monolithic process?
EDIT: code for the module is here.
It could just be that you need to use an editor better suited to reading large VHDL files. I regularly work with 3000+ line VHDL files where most of the space is the logic of a single process, and have no difficulties reading them due to an editor that supports code folding.
I use Notepad++, but I'm sure there are other editors that can support folding on VHDL syntax. When I open a file, I press alt+0 to fold every possible syntax folding point then expand as needed to the part I'm working on. You can also use line hiding to fold arbitrary sections of your file, although that's a little more awkward to work with.
If you have large groups of related concurrent statements you can easily group them into a folding point with a name : if true generate which also allows you to declare intermediate signals outside of the scope of your main architecture (block statements work, but aren't supported by all tools). To force a folding point within a process I use if true then.
If you are designing a processor that implements the different operations in a giant case statement, then what you are really describing is a series of parallel functional units, feeding an output multiplexer. You might have an output that is driven, depending on the op mode, by the output of either a multiplication, addition, subtraction, some logic operation, a shift, etc.
You can easily design this in a modular way, by implementing each functional unit in its own entity, some of which might be quite simple. In the first instance, these blocks would operate unconditionally, and their outputs would feed an output multiplexer. You might later add enable signals, driven by your instruction decoding logic, that enable only the blocks that will be used in a particular operation, in order to save power. It might sound like you will end up with a lot of control signals using this approach, but if you put them all in a record, it makes the code quite compact, while at the same time allowing verbosity and readability at the point where a control signal is used, for example:
AddSub : entity work.AdderSubtractor
port map (
clk => clk,
enable => decoded_instruction.addsub_enable,
a => a,
b => b,
mode => decoded_instruction.addsub_mode, -- This might be an enumerated type
output => addsub_output
);
There would be other _output signals, and at the end you would have something like
OutputMux : process (all)
begin
case decoded_instruction.output_mux_select is
when ADD_SUB => output <= addsub_output;
when MULT => output <= mult_output;
when LOGIC => output <= logic_output;
end case;
end process;
One bonus of doing it this way is that you might find it efficient for several of the functions to be implemented in a DSP block in the FPGA; you can easily design a functional block for add, subtract, multiply, written to target the DSP block in your device. The output of this would be just another input to your 'output' multiplexer. In my experience you should be able to efficiently implement many of your processing functions using a single DSP block (or a single entity that describes a few cascaded DSP blocks, depending on your data path width).
Personally I much prefer this approach of making the design very modular. In a recent multicore DSP project, I have only a couple of files that have ~500 lines, with the majority having 200 or less. This means that when I come back to a part of the design, it usually fits on one page, and can easily be picked up and understood in a very short amount of time. I also find that when implementing heavy pipelining to improve the performance of the design, having too much going on in one process or entity can make this job an order of magnitude more difficult.
Lastly, if functional elements are contained in small entities, you can more easily simulate, test, and verify just that bit of code in isolation, which in my experience allows the block to be signed off more quickly, while at the same time giving more confidence in the code. If everything is in one process, it is harder to have confidence that making a change that fixes or improves one thing, isn't going to break something else. Again in a heavily pipelined design, I find that it can be quite easy to change something that inadvertently causes the design to fail an aggressive timing constraint, so the simpler the entities, the smaller the chances of this happening.
As said, your question is hard to answer. How many lines are we talking about?
You could look up good VHDL code practises though:
- aliases should be avoided (not all tools even support then AFAIK)
- give signals/variables a clear name
- try to group functionality
- try not to change a signal/variable on 2 places separated by 500lines, usually there is a way
- if really needed you could consider using shared variables, introduced in VHDL93. (this will, however, not solve your multiple driver issue)
- do not forget the availability of records to group signals
About making your "intermediate signals visible", you could write
junk_proc: process(clk, rst) is
variable a,b,c: of_some_types;
begin
if rst then
//do reset stuff
elsif rising_edge(clk)
b:=func1(a);
c:=func2(b);
end if;
end process;
variables a,b and c (plain wires in this case) could obviously be visualized in any simulation tool.
If, however, you write b=func1(func2(func3(func4(a)))), do not forget that you describe all this to happen in a single clock cycle. Considering your description I bet you'll run into problems, but perhaps that's a good way of learning.
What is main differences between if else and case statement in VHDL. Although both look similar and sometime replace each other.but What logic circuit appear after synthesis . When should we go for if else or case statement ?
Assuming an if-statement and a case-statement describes the same behavior, then the resulting circuit is likely to be identical after the synthesis tools done the translation and optimization.
As Paebbels writes in the comment, the details are described for each tool in the relevant synthesis guide, and there are probably tool-dependent cases where the result may differ, but as a general working assumption, then the synthesis tool will get to the same circuit for equivalent if-statements and case-statements.
The critical point is usually to make correct and maintainable VHDL code, and here readability counts, so choose an if-statement or a case-statement depending on what makes the code most straight forward, and don't try to control the resulting circuit through VHDL constructions, unless there is a specific reason that this is required.
Note that in the if-statement early conditions takes priority over later, but in the case-statement all when have equal priority.
Remember that VHDL is parallel programming language and a form of declarative programming see here as opposed to procedural programming like c/c++ and another other sequential language.
This means in essence, you are telling or attempting to describe to the compiler with your code what the behavior should be, and not specifically telling it what to do or what the behavior is like with procedural programming. This might be what prompted you to ask the question.
Now remember however, that the sequencing of the if or case will affect synthesis. With FPGA's nowadays, all combinatorial part of the logic are in the form of Loop up tables which are internally designed as cascaded arrays multiplexers grouped together to form LUTs with input number N commonly 4 See here for more details, and the compiler decides how to configure these arrays of LUTs.
The ordering can affect the number of cascaded multiplexer that the compiler calculates before the output is resolved.
Note that although in theory, it is possible to get the same behaviour for both if and switch. Case is looking at a single variable and deciding cases for each possible outcome while an If statement can be applied to multiple variables at the same time.
So flexibility? I would say goes to If. However with great power comes great responsibility, if is easy it use several signals from everywhere and if not done properly can lead to bad design, ie coupling of too many variable and any change is subject to failure due to too many dependency issues. Case is suitable for state machines but that is also true for procedural languages I suppose.
In addition, if you use too many different signals to act as conditions to your If, it can affect timing. which may mean limitation in your clock frequency, if you are working with high speed and the list goes on. clock skew, need to constrain signals etc.
Is it a good design practice to use combinatorial logic to drive the output of a module in VHDL/Verilog?
Is it okay to use the module input directly inside a combinatorial block,and use the output of that combinatorial block to drive another sequential block in the same module?
An answer to the two questions really depends on the overall design methodology
and conditions, and will be opinion based, as Morgan points out in his comment.
The questions are in special relevant for a large design with timing pushed to
the limit, and where multiple designers contribute with different modules. In
this case it is important to determine a design methodology up front which
answers the two questions, in order to ensure that modules provided by
different designers can be integrated smoothly without timing issues.
Designing with flip-flops on all outputs of each module, gives the advantage
that when an output is used as input to other module, then the input timing is
reasonable well defined, and only depends on the routing delay. This makes it
a Yes to question 1.
Having a reasonable well-defined input timing makes it possible to make complex
combinatorial logic directly on the inputs, since most of the clock cycle will
be available for this. So this also makes it a Yes to question 2.
With the above Yes/Yes design methodology, the available cycle time is only
used once, and that is at the input side of the module, before the flip-flops
that goes on the output. The result is that multiple modules will click nicely
together like LEGO bricks, as shown in the figure below.
If a strict design methodology is not adhered to in different modules, then
some modules may place flip-flops on the input, and some on the output. A
longer cycle time, thus slower frequency, is then required, since the worst
case path goes through twice the depth of combinatorial logic. Such a design
is shown in the figure below, and should be avoided.
A third option exists, where flip-flops are placed on all inputs, and the
design will look like the figure below if two different modules use the same
output.
One disadvantage with this approach is that the number of flip-flops may be
higher, since the same output is used as input to multiple flip-flops, and the
synthesis tool may not combine these equivalent flip-flops. And even more
flip-flops than this may be required, if the module that generates the output
will also have to make a flip-flopped version for internal use, which is often
the case.
So the short answer to the questions is: Yes and Yes.
The answer to both questions as expressed is basically yes, provided the final design meets speed targets, and the input signals are clean.
The problem with blocks designed this way are that the signal timings through them are not accurately defined, so that combining several such blocks may result in an absurdly slow design, or one in which fast input signals don't propagate cleanly through the design.
If you design such a circuit, and it meets ALL your input and output timing constraints as well as any clock speed constraints you set, it will work.
However if it fails to meet the clock constraints you will have to insert registers to "pipeline" the design, breaking up long slow chains of combinational logic. And you will have to observe the input and output timings reported by synthesis and PAR, and they can get complicated.
In practice (in an FPGA : ASICs can be different) registers are free with each logic block (Xilinx/Altera, not true for Actel/Microsemi) and placing registers on each block's inputs and/or outputs makes the timings much simpler to understand and analyse.
And because such a design is pipelined, it is normally also much faster.
I have a clock in my vhdl code but i don't use it , simply my process just depends on handshake when one component finishes and gets an output out , this output is in the sensitivity list of my FSM and is then becomes an input to the next component and of course its output is also in the sensitivity list of my FSM(so to know when will component finishes its computation)... and so on.
Is this method wrong ? it works in simulation and also in post-route simulation but gets me warnings like this : warning :HOLD High VIOLATION ON I WITH RESPECT TO CLK; and
warning :HOLD Low VIOLATION ON I WITH RESPECT TO CLK;
is this warnings not important or will my code damage my fpga because it doesn't depend on a clock ?
The warning you are getting are timing violations. You get these because the tools detect that your design does not obey the necessary timing restrictions for the internal primitives.
For instance, inputs to lookup-tables (which is one of the main building-blocks inside an FPGA) need to be held for a specific time for the output to stabilize. This is very hard to guarantee when your entire timing relies only on the latencies and delays of the components themselves, and switch on a completely asynchronous basis.
Depending on your actual design (mostly the size and complexity of it), I'll wager the guess that you'll end up with a lot of very-hard-to-debug errors once you get it inside an FPGA. You'll have a much, much, much easier time using a clock. This will allow you to have a clear idea of when signals arrive where, and it will allow you to use the internal tools to check your timing. You'll also find it much easier to interface to other devices, and your system will be less susceptible to noisy inputs.
So all in all, use a clock. You (probably) wont damage your FPGA by not doing it, but a clock will save you from tons of trouble.
your code does most probably not damage your FPGA because it doesn't depend on a clock. however, for synthesis you should always use registered (clocked) logic. without using a clock your design will not be controllable because of timing/delay/routing/fan out/... this will let your FSM behave "mysteriously" when synthesized (even if it worked in simulation).
you'll find plenty of examples for good FSM implementation style with google's help (search for Moore or Mealy FSM)
Definitely use a clock. And only one clock throughout the design. This is the easiest way - the tools support this design style very well. You can often get away with a single timing constraint, especially if your inputs are slow and synchronous to the same clock.
When you have gained experience designing this way, you can move outside of this, but be ready for more analysis, timing constraints and potentially build iterations while you learn the pitfalls of crossing clock-domains and asynchronous signals.
I am aware of the need to synchronize all inputs to an FPGA before using those inputs in order to avoid metastability. I'm also aware of the need to synchronize signals that cross clock domains within a single FPGA. This question isn't about crossing clock domains.
My question is whether it is a good idea to routinely register all of the inputs and outputs of every internal hardware module in an FPGA design. The rationale is that we want to break up long chains of combinational logic in order to improve the clock rate so that we can meet the timing constraints for a chosen clock rate. This will add additional cycles of latency proportional to the number of modules that a signal must cross. Is this a good idea or a bad idea? Should one register only inputs and not outputs?
Answer Summary
Rule of thumb: register all outputs of internal FPGA cores; no need to register inputs. If an output already comes from a register, such as the state register of a state machine, then there is no need to register again.
It is difficult to give a hard and fast rule. It really depends on many factors.
It could:
Increase Fmax by breaking up combinatorial paths
Make place and route easier by allowing the tools to spread logic out in the part
Make partitioning your design easier, allowing for partial rebuilds.
It will not magically solve critical path timing issues. If there is a critical path inside one of your major "blocks", then it will still remain your critical path.
Additionally, you may encounter more problems, depending on how full your design is on the target part.
These things said, I lean to the side of registering outputs only.
Registering all of the inputs and outputs of every internal hardware module in an FPGA design is a bit of overkill. If an output register feeds an input register with no logic between them, then 2x the required registers are consumed. Unless, of course, you're doing logic path balancing.
Registering only inputs and not outputs of every internal hardware module in an FPGA design is a conservative design approach. If the design meets its performance and resource utilization requirements, then this is a valid approach.
If the design is not meeting its performance/utilization requirements, then you've got to do the extra timing analysis in order to reduce the registers in a given logic path within the FPGA.
My question is whether it is a good idea to routinely register all of the inputs and outputs of every internal hardware module in an FPGA design.
No, it's not a good idea to routinely introduce registers like this.
Doing both inputs and outputs is redundant. They'll be no logic between the output register and the next input register.
If my block contains a single AND gate, it's overkill. It depends on the timing and design complexity.
Register stages need to be properly thought about and designed. What happens when a output FIFO fills or other stall conditions? Do all signals have the right register delay so that they appear at the right stage in the right cycle? Adding registers isn't necessarily as simple as it seems.
The rationale is that we want to break up long chains of combinational logic in order to improve the clock rate so that we can meet the timing constraints for a chosen clock rate. This will add additional cycles of latency proportional to the number of modules that a signal must cross. Is this a good idea or a bad idea?
In this case it sounds like you must introduce registers, and you shouldn't read the previous points as "don't do it". Just don't do it blindly. Think about the control logic around the registers and the (now) multi-cycle nature of the logic. You are now building a "Pipeline". Being able to stall a pipeline properly when the output can't write is a huge source of bugs.
Think of cars moving on a road. If one car applies it's brakes and stops, all cars behind need to as well. If the first cars brake lights aren't working, the next car won't get the signal to brake, and it'll crash. Similarly each stage in a pipeline needs to tell the previous stage it's stopping for a moment.
What you can find is that instead of having long timing paths along your computation paths going from input to output, you end up with long timing paths on your enable controlling all these register stages from output to input.
Another option you have is, to let the tools work for you. Add add the end of your complete system a bunch of registers (if you want to pipeline more) and activate in your synthesis tool retiming. This will move the registers (hopefully) between the logic where it is most useful.