Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

VHDL using a stimulus for one clock cycle

Status
Not open for further replies.

FPGAwarrior

Newbie level 5
Newbie level 5
Joined
Jan 28, 2020
Messages
10
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
70
I have VHDL code with about 20 processes. One process, I call Main_Loop has a variable I called gate. If certain conditions are met, the value of gate changes. Most processes are triggered by a gate value. I need a testbench that will allow me to jump to a certain process. For example.

Code:
process -- testbench code
begin
        if gate = 2 then
        gate <= to_unsigned(30, 6);
        wait;
        end if;
end process;

This tb process changes gate to 30. However, after the process is "turned on" by 30. My code then changes gate to 31. Now when I run Modelsim, my code never changes to 31 due to the tb.
I could change the above "wait" to wait for 10ns and write another tb process like:
Code:
process -- tb code
        if gate = 30 then
        gate <= "release state";
        wait;
        end if;
end process;

or just use...

Code:
gate <= "release state";

How does one un-define an integer like my gate value or is there another/better way?

[moderator action: added CODE tags]
 
Last edited by a moderator:

The question title talks about clock cycles. I would expect a clock edgle triggered process in the tb then.
 
Like has been mentioned, you need to generate the clock signal.

Now if you say for one clock cycle and you are using if statement, then whatever assignment you make is expected to be implemented in the next clock edge.

If you change the 'wait' statement to a 'wait for' statement with 10 ns, then you'd be expecting the value 30 to be constantly assigned to gate every 10 ns and the gate value will not change as the value does not change. So you can leave the if statement for now and assign values to gate after certain intervals of time with only the 'wait for' statement. You'll definitely need a 'wait' statement after your last assignment so that the process is suspended, else it will start all over again.

I don't understand what is meant by 'un-define' an integer. If by that you are referring to the length of the vector, then you should use gate'length instead of 6.

Actually, if the gate signal is to change by certain conditions, then you should be looking to meet those conditions with your test bench assignments rather than assigning values to gate itself.

Obviously, this will take more than one clock cycle.
 
Last edited:

Are Main_Loop and the other 20 processes part of the test bench, or are they something you expect to run in an FPGA?
 

I've been rather confused by your descriptions of the issues you are having over multiple threads and the code you are posting.

It starting to appear that you are treating VHDL as if it is going to behave as if it is a software program. You treat signals as if they are globals in a software programming language and they can be assigned anywhere in the code by any process.

You can only assign a signal in a single process, otherwise you will have multiple driver issues on the signal. You should think about what multiple processes mean in regards to the HW produced after synthesis. Multiple drivers would be like taking a 74HC240 and shorting all the outputs together and driving the inputs with various high and low values. This causes driver contention, which is why a synthesis tool will complain about the structure of the code.

To create a testbench with a signal connected to a UUT with INOUT ports you need to treat the testbench signals generating the stimulus to the UUT as tri-state signals. You enable the stimulus to the UUT when the UUT INOUT signals are not being driven (Hi-Z) and Hi-Z your stimulus signals when the UUT is driving the INOUT port.

Your idea of "undefining" the signal is a software concept. It is not possilbe to make a hardware circuit exist sometimes and then not exist at other times. The TB will need to represent what would need to exist to run a physical UUT.
 

I will try to be more clear. My working VHDL main code has about 20 processes. My VHDL-tb has just one process with no name with an IF statement as was shown. My working VHDL does the following: Inside Main_Loop a variable "gate" starts at '0' from the signal initialization. The Main_loop process looks like the following:

Code:
if gate = 0 then
then gate <= 2;
ml_timer = 0;
end if;

if gate = 2 and ml_timer > 50000000 then -- allow power to stabilize
gate <= 3;
ml_timer <= 0;
end if;
...etc.
-- The gate value keeps progressing...
For example:

Code:
if gate = 29 then
--do something
gate <= 30;
end if;

If gate = 30 and sd_latch = '0' then
gate = 31;
end if;

-- Now another process in the main code...
Code:
Serial_Data: process(CLK)
begin
 IF (rising_edge(CLK)) THEN
        if (sd_latch = '0' and gate = 30) then
                sd_latch <= '1'; -- Makes this process active
       end if;
if sd_latch = '1' then
-- do something and set sd_latch <= '0' when completed
end if;
END IF; -- rising edge IF always capitalized.

As you see my Serial_Data process is triggered by gate = 30 by one clock cycle.
The "gate" value is controlled by Main_Loop and read by others.

Currently, inside Main_Loop process, I have the following temporary code at the top:
Code:
if gate = 2 then -- Testbench Modelsim.
gate <= 30;       -- Testbench Modelsim.
end if;                -- Testbench Modelsim.


Note that this code, in part, generates gate=30 for one clock cycle. However, it may not be a good idea to put disposable code in the main code.

Now back to tb code.
I want to put a similar one cycle jump in my tb code because I have several gate triggers I need to test. The value of gate should, as per tb, set gate=30 and then go to a wait state and let the main code change the value of gate as needed. Note that I will be trying to drive the value of "gate" by two processes, Main_Loop and an un-named process inside of tb. Could be against VHDL law. I used the term "un_define" because the main code needs to drive the value of "gate". I guess "release" would have been a better term.
--- Updated ---

I am treating only the tb like software. My Serial_Data process does not have any outside of chip input. Other than adding temporary code in the main code as I have done, How does one inject the needed trigger value using tb code?

[moderator action: addeed CODE tags]
 
Last edited by a moderator:

In order to be able to reference "gate", you need to declare an external name in your test bench. In order to make assignment to "gate" from your test bench, you need to use force assignments to assign values to the external name that references it. In order to stop forcing, you need to use release assignment against the external name to do that.
--- Updated ---

This is available with VHDL-2008.
 
Last edited:

I just looked at force and release. The examples I saw looked so convoluted, I closed the web page.
 

Yes, it's something that has to be duly studied and practiced.

I could refer you to documents on the topic. One of such is a very good book in VHDL that I have read myself. Designer's Guide to VHDL by Peter J. Ashenden and Jim Lewis. It's a very good book and very detailed too. Very good authors I must say. I am sure that your problem is duly treated in the book.

Cheers!
 

@FPGAwarrior,

Just my 2 cents, for a good testbench:
1. Drive all signals from the testbench, exercise the DUT exactly as it would be in silicon.
2. You can use the force signal feature, but only in special cases, if you have a good reason and really have to use it.
 
@FPGAwarrior,

Just my 2 cents, for a good testbench:
1. Drive all signals from the testbench, exercise the DUT exactly as it would be in silicon.
2. You can use the force signal feature, but only in special cases, if you have a good reason and really have to use it.
Exactly this.

Drive all the signals from the testbench. if the testbench can't determine when it can drive the signals, then any board you put the design on won't be able to determine when it can drive the signals.

The only time I've ever forced a signal inside of a design was to emulate a fault condition, which can't be generated from the pins.
 

Thank you all. I do have a test bench flag TbFlag in my code that I can drive with my test bench. My main code is about 4000 lines and 5 files. I am currently adding more documentation for each line. Because signals are generated in one process and I do prefix label all signals with "xx_" so I can look at the two letters to get origin. I want it to be easier to read. I have several "and/or TbFlag(x) = '1' " snippets for the test bench. I need this code to be readable and clean. I wanted to remove the TbFlags but now I can live with them.
One other point for others. I use an RPi (spi and tkinter) with a three wire serial connection. It allows me to see about 30 signals in slow real time from my FPGA(~ 640 KHz on the clk). RPi, SignalTap and testbench are necessary for me to get my 1 minute long code to work properly. The FPGA does a lot of number crunching in that time and in real time on demand.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top