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 Verification with processes on FPGA

Totodile

Newbie level 5
Newbie level 5
Joined
Apr 22, 2025
Messages
9
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
101
Hello all,

Is there an issue in verifying my VHDL testbench with processes?

I was thinking about reporting either success or error conditions and then check the simulation transcript for any error.
If I find one, then the simulation reports failed, if none, then it should be passed.

My only problem is that I'm verifying an 8251 IP Core.
I've managed to use the init_signal_spy to spy under submodules and then, for example, I'm checking the baud rates for the start_bit like this:

Code:
if rising_edge(spy_tx_clock) then
        if mode(1 downto 0) = "00" then
            report "Error: There is no Synchronous Mode";
        elsif mode(1 downto 0) = "01" then
            baud_count := 1;
        elsif mode(1 downto 0) = "10" then
            baud_count := 16;
        elsif mode(1 downto 0) = "11" then
            baud_count := 64;
        end if;
            
        -- Detect when we first enter START_BIT state
        if spy_txd_state = START_BIT and not counting_started then
            counting_started := true;
            internal_count := 0;
            test <= '1';
            report "Start bit detected, beginning count" severity note;
        end if;
        
        -- If we're counting, increment on each rising edge
        if counting_started then
            if internal_count < baud_count then
                -- Still counting within START_BIT
                internal_count := internal_count + 1;
            elsif internal_count = baud_count then
                -- This is where we expect the state to change
                if spy_txd_state = DATA_OUT then
                    report "Success: State correctly changed to DATA_OUT after " & integer'image(baud_count) & "  counts" severity note;
                    test <= '0';
                    counting_started := false;
                else
                    report "Error: Expected state to change to DATA_OUT after" & integer'image(baud_count) & "  counts. ";
                    test <= '0';
                    counting_started := false;
                end if;
            end if;
        end if;
        
        -- Reset if state unexpectedly changes before
        if counting_started and internal_count < baud_count and spy_txd_state /= START_BIT then
            report "Error: State changed from START_BIT prematurely after ";
            counting_started := false;
            test <= '0';
        end if;
    end if;

I still need to extend this baud rate generator to the rest of my FSM.
On queue I have processes I want to introduce to verify the UART such as :

Data checker, a Loopback test, and some functionalities that exist on the 8251.

Is this a correct approach to solve this?


Cheers,
Totodile
 
WRT the title - we use processes to check the DUT all the time.

OTOH, if possible, I try to avoid signal spy - or external names, the VHDL-2008 equivalent to signal spy.

Have you considered checking the baud rate by sending particular data words - such as X"AA" and X"55". From there you can observe the smallest value for the serial data out line changing. Note I have code in here to instruct the DUT to generate the serial data values. This is not going to match your DUT so well as you have not given enough of a picture your DUT and what you are trying to accomplish.

Code:
Architecture Test1 of TestHarness is
  variable SmallestPeriod : time := time'high ;
begin
  FindSmallestPeriod : process (SerialData)
    variable LastChange : time := 0 ns ;
    variable CurrentPeriod : time ;
  begin
    CurrentPeriod := now - LastChange ;
    if CurrentPeriod < SmallestPeriod then
      SmallestPeriod <= CurrentPeriod ;
    end if ;
  end process ;

  TestGen : process
  begin
    Send(UartRec, X"AA")  ;
    Send(UartRec, X"55") ;
    if SmallestPeriod /= EXPECTED_BAUD then
       report "SmallestPeriod: " & to_string(SmallestPeriod) &
              " does not match EXPECTED BAUD: " & to_string(EXPECTED_BAUD) ;
    end if ;

    . . .

With respect to checking, the report statements are not so great. You can do better by adopting a methodology such as OSVVM (see osvvm.org and github.com/OSVVM/OsvvmLibraries).

In OSVVM, there is a package that helps track errors. To use it for the self-checking, the above would change to:
Code:
library osvvm;
context osvvm.OsvvmContext ;
entity TestHarness is
...
  TestGen : process
  begin
    SetTestName("Test1") ;
    SetLogEnable(PASSED) ;
    Send(UartRec, X"AA")  ;
    Send(UartRec, X"55") ;
    -- Check SmallestPeriod matches EXPECTED_BAUD match
    AffirmIfEqual(SmallestPeriod, EXPECTED_BAUD) ;   -- Error counts are tracked in a singleton data structure in OSVVM's AlertLogPkg package
    . . .
    -- Generate Text and HTML reports
    EndOfTestReports ;
    std.env.stop ;
  end process TestGen ;
    . . .

The "Send" in the above is a procedure call that either implements the transaction sent to the DUT or it would need to be done in the DUT and received by the testbench.
 
Last edited:

LaTeX Commands Quick-Menu:

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top