|
| 1 | +-- EMACS settings: -*- tab-width: 2; indent-tabs-mode: t -*- |
| 2 | +-- vim: tabstop=2:shiftwidth=2:noexpandtab |
| 3 | +-- kate: tab-width 2; replace-tabs off; indent-width 2; |
| 4 | +-- ============================================================================= |
| 5 | +-- Authors: Patrick Lehmann |
| 6 | +-- Gustavo Martin |
| 7 | +-- |
| 8 | +-- Entity: sync_Bits_TestController (Simple architecture) |
| 9 | +-- |
| 10 | +-- Description: |
| 11 | +-- ------------------------------------- |
| 12 | +-- OSVVM simple test for flag signal synchronizer. |
| 13 | +-- Tests that signals propagate correctly across clock domains. |
| 14 | +-- |
| 15 | +-- License: |
| 16 | +-- ============================================================================= |
| 17 | +-- Copyright 2025-2025 The PoC-Library Authors |
| 18 | +-- Copyright 2007-2016 Technische Universitaet Dresden - Germany |
| 19 | +-- Chair of VLSI-Design, Diagnostics and Architecture |
| 20 | +-- |
| 21 | +-- Licensed under the Apache License, Version 2.0 (the "License"); |
| 22 | +-- you may not use this file except in compliance with the License. |
| 23 | +-- You may obtain a copy of the License at |
| 24 | +-- |
| 25 | +-- http://www.apache.org/licenses/LICENSE-2.0 |
| 26 | +-- |
| 27 | +-- Unless required by applicable law or agreed to in writing, software |
| 28 | +-- distributed under the License is distributed on an "AS IS" BASIS, |
| 29 | +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 30 | +-- See the License for the specific language governing permissions and |
| 31 | +-- limitations under the License. |
| 32 | +-- ============================================================================= |
| 33 | + |
| 34 | +library IEEE; |
| 35 | +use IEEE.std_logic_1164.all; |
| 36 | +use IEEE.numeric_std.all; |
| 37 | + |
| 38 | +library osvvm; |
| 39 | +context osvvm.OsvvmContext; |
| 40 | + |
| 41 | +library PoC; |
| 42 | +use PoC.utils.all; |
| 43 | + |
| 44 | + |
| 45 | +architecture Simple of sync_Bits_TestController is |
| 46 | + signal TestDone : integer_barrier := 1; |
| 47 | + |
| 48 | + constant TCID : AlertLogIDType := NewID("TestCtrl"); |
| 49 | + |
| 50 | + constant INIT : std_logic_vector(Sync_out'range) := (others => '0'); |
| 51 | + |
| 52 | +begin |
| 53 | + ControlProc : process |
| 54 | + constant ProcID : AlertLogIDType := NewID("ControlProc", TCID); |
| 55 | + constant TIMEOUT : time := 10 ms; |
| 56 | + begin |
| 57 | + SetTestName("sync_Bits_Simple"); |
| 58 | + |
| 59 | + SetLogEnable(PASSED, FALSE); |
| 60 | + SetLogEnable(INFO, FALSE); |
| 61 | + SetLogEnable(DEBUG, FALSE); |
| 62 | + wait for 0 ns; wait for 0 ns; |
| 63 | + |
| 64 | + TranscriptOpen; |
| 65 | + SetTranscriptMirror(TRUE); |
| 66 | + |
| 67 | + wait until Reset = '0'; |
| 68 | + ClearAlerts; |
| 69 | + |
| 70 | + WaitForBarrier(TestDone, TIMEOUT); |
| 71 | + AlertIf(ProcID, now >= TIMEOUT, "Test finished due to timeout"); |
| 72 | + AlertIf(ProcID, GetAffirmCount < 1, "Test is not Self-Checking"); |
| 73 | + |
| 74 | + EndOfTestReports(ReportAll => TRUE); |
| 75 | + std.env.stop; |
| 76 | + end process; |
| 77 | + |
| 78 | + StimuliProc : process |
| 79 | + constant ProcID : AlertLogIDType := NewID("StimuliProc", TCID); |
| 80 | + begin |
| 81 | + -- Initialize |
| 82 | + Sync_in <= INIT; |
| 83 | + |
| 84 | + wait until Reset = '0'; |
| 85 | + WaitForClock(Clock1, 4); |
| 86 | + |
| 87 | + -- Toggle input several times with different patterns |
| 88 | + Sync_in <= "1"; |
| 89 | + WaitForClock(Clock1, 2); |
| 90 | + |
| 91 | + Sync_in <= "0"; |
| 92 | + WaitForClock(Clock1, 2); |
| 93 | + |
| 94 | + Sync_in <= "1"; |
| 95 | + WaitForClock(Clock1, 2); |
| 96 | + |
| 97 | + Sync_in <= "0"; |
| 98 | + WaitForClock(Clock1, 6); |
| 99 | + |
| 100 | + Sync_in <= "1"; |
| 101 | + WaitForClock(Clock1, 16); |
| 102 | + |
| 103 | + Sync_in <= "0"; |
| 104 | + WaitForClock(Clock1, 2); |
| 105 | + |
| 106 | + Sync_in <= "1"; |
| 107 | + WaitForClock(Clock1, 2); |
| 108 | + |
| 109 | + Sync_in <= "0"; |
| 110 | + WaitForClock(Clock1, 6); |
| 111 | + |
| 112 | + wait; |
| 113 | + end process; |
| 114 | + |
| 115 | + CheckerProc : process |
| 116 | + constant ProcID : AlertLogIDType := NewID("CheckerProc", TCID); |
| 117 | + variable toggled : natural := 0; |
| 118 | + variable Sync_out_old : std_logic_vector(Sync_out'range); |
| 119 | + begin |
| 120 | + wait until Reset = '0'; |
| 121 | + WaitForClock(Clock2); |
| 122 | + |
| 123 | + -- Check initial value |
| 124 | + AffirmIf(ProcID, Sync_out = INIT, "Initial value should be " & to_string(INIT)); |
| 125 | + Sync_out_old := Sync_out; |
| 126 | + |
| 127 | + -- Count toggle events for a maximum of 50 clock cycles |
| 128 | + for i in 1 to 50 loop |
| 129 | + WaitForClock(Clock2); |
| 130 | + if Sync_out /= Sync_out_old then |
| 131 | + toggled := toggled + 1; |
| 132 | + Sync_out_old := Sync_out; |
| 133 | + end if; |
| 134 | + end loop; |
| 135 | + |
| 136 | + -- Should see 8 toggle events based on stimuli |
| 137 | + AffirmIf(ProcID, toggled = 8, |
| 138 | + "Expected 8 toggle events, got " & integer'image(toggled)); |
| 139 | + |
| 140 | + WaitForBarrier(TestDone); |
| 141 | + wait; |
| 142 | + end process; |
| 143 | + |
| 144 | +end architecture; |
| 145 | + |
| 146 | + |
| 147 | +configuration sync_Bits_Simple of sync_Bits_TestHarness is |
| 148 | + for TestHarness |
| 149 | + for TestCtrl : sync_Bits_TestController |
| 150 | + use entity work.sync_Bits_TestController(Simple); |
| 151 | + end for; |
| 152 | + end for; |
| 153 | +end configuration; |
0 commit comments