Add to your testbench a monitor process that watches the output and compares it to the expected value, allowing for the delays through the filter.
Your VHDL style is better than some - even better than some textbook examples I have seen, but still: a few comments :
Using named rather than positional assignment for the "dff"
component instantiations would save possible confusion between inputs
and outputs for anyone trying to follow the pipeline. This doesn't
really matter here, because :
you can eliminate the dffs altogether; replace them with lines
of the form Q1 <= MCM3;
in the same clocked process as Yout <=
add_out3;
that greatly simplifies the whole filter.
You can reduce number of conversion functions by making H0..3 integer types; and if they are constant, make them constants! As multiplication between signed and integer is defined,no other changes are required.
type coefficient is new integer range -128 .. 127;
constant H0 : coefficient := -2;
Lose the redundant parentheses in if ( rising_edge(Clk) ) then
- this isn't C!
The DRY principle applies in VHDL too... there are several ways to apply it to the testbench : my choice would be a local procedure.
stim_proc: process
procedure Input(D : in integer range -128 .. 127) is
begin
Xin <= to_signed(D,8);
wait for clk_period*1;
end Input;
begin
wait for Clk_period*2;
Input(-3);
Input( 1);
I will leave it to an LRM expert to provide a more detailed answer, but in short, your approach should be valid - I ran a quick test with a recent version of Quartus, and it handles '-'
like it's supposed to - the logic generated is reduced as expected when the output is defaulted to '-'
('X'
works too, by the way). More on the approaches you listed:
Not assigning the signal isn't really an option for your example, of course, if you don't want latches. If it's a clocked process, you're slightly better off, but you'll still get enables where you might not need them. Maybe I'm missing your intent here.
'-'
, as previously noted, is probably the best option, for both semantic and practical reasons.
Depends on what you mean by "undefined". 'X'
is technically "unknown". 'U'
is for uninitialized signals, which ModelSim displays as "X"
for hex representations. 'X'
does seem to work, though, as I noted above.
Another alternative would be to do the optimization yourself and remove one case from being tested explicitly:
if instruction(15 downto 8) = "11111001" then
write_data <= std_ulogic_vector(resize(signed(instruction(7 downto 4)), 16));
else
write_data <= std_ulogic_vector(resize(signed(instruction(7 downto 0)), 16));
end if;
This has significant disadvantages (mostly related to code clarity), though, and I would probably opt for a more ideal solution.
Incidentally, '-'
is also commonly used with std_match()
, which I would consider using for your decoding, e.g.:
if std_match(instruction(15 downto 8), "1100----") then
Though at that point, you're probably better off just using case?
.
Best Answer
To avoid latches, you need to make sure all of your outputs are assigned at all possible branches of the code.
for example,
would generate a latch, because in the first condition, the value of b(1) is not specified, so the compiler decided you wanted to keep the previous value of b(1) there. One way to write this that would not generate a latch is:
Here you explicitly state that b should retain it's old value, and then overwrite b(0) with the new value.
Another way is to give b a default value, as in @TomiJ's answer.
If you post the code you are getting a latch on, we could help you find the specific reason.