I am trying to verify a design written in VHDL using SystemVerilog's assertions. however I got a problem when I have a non defined signal'X'
Just for example here is a code of a Comparator:
entity FP_comparator_V2 is
port (
comp_in1 : in std_logic_vector(31 downto 0);
comp_in2 : in std_logic_vector(31 downto 0);
less : out std_logic;
equal : out std_logic;
greater : out std_logic
);
end FP_comparator_V2;
architecture behav of FP_comparator_V2 is
-- signal, component etc. declarations
begin
-- architecture body
process(comp_in1, comp_in2)
begin
if comp_in1 = comp_in2 then
equal <= '1';
less <= '0';
greater <= '0';
else
equal <= '0';
...
end if;
end process;
end behav;
and the assertions
property FP_Comparator_V2_1_1;
#(posedge `assertion_check_clk29M4912 or negedge `assertion_check_clk29M4912)
(fp_comp_intf.Comp_in1 === fp_comp_intf.Comp_in2) |-> (fp_comp_intf.equal);
endproperty
DS_3_4_69_1_1:
assert property(FP_Comparator_V2_1_1);
cover property(FP_Comparator_V2_1_1);
property FP_Comparator_V2_1_2;
#(posedge `assertion_check_clk29M4912 or negedge `assertion_check_clk29M4912)
(fp_comp_intf.Comp_in1 !== fp_comp_intf.Comp_in2) |-> (!fp_comp_intf.equal);
endproperty
DS_3_4_69_1_2:
assert property(FP_Comparator_V2_1_2);
cover property(FP_Comparator_V2_1_2);
When Comp_int1 and Comp_int2 have defined values the simulation works fine if one of them have a undefined value also works fine but when both signals have undefined value it gives error For example :
Comp_int1= 48xx_xxxx; Comp_int2=47xx_xxxx ==>Equal = 1
I suppose it compares bit by bit so Equal should be '0' Please if you know a book or a website explaining the behavior of signals after synthesis or the logic behind undefined signals I would be thankful if you put it in a comment
thank you
I would suggest eliminating undefined values for signals in the design first. You can do this by initializing values to those signals in all possible cases. This helps in eliminating the X-propagation in the design.
Related
I'm trying to create a simple push button in VHDL that turns on after an input switch or pb goes from 0 to 1 to 0 using a clock and a process. However, my code seems to be giving me undefined output. Here's what I have so far.
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
Entity captureInput is port
(
CLK : in std_logic := '0';
RESET_n : in std_logic := '0';
buttonState : in std_logic := '0';
buttonOut : out std_logic := '0'
);
end Entity;
ARCHITECTURE one of captureInput is
signal lastButtonState: std_logic := '0';
signal btnState : std_logic := '0';
BEGIN
process (CLK, RESET_n) is
begin
if (RESET_n = '0') then
lastButtonState <= '0';
elsif (rising_edge(CLK)) then
if (buttonState ='0' and lastButtonState = '1') then
btnState <= '1';
end if;
lastButtonState <= buttonState;
end if;
end process;
buttonOut <= btnState
end;
Try to initialize your btnState in the reset branch of your register and also have an else statement where you set your btnState back to 0, under some condition. I would bet that your undefined output comes from the fact that you do not define your btnState anywhere else outside your if conditions. It's good practice to not rely on the initial value of your declaration: Synthesis tools ignore it and some simulators will as well. Also, remember that the clocked body of the if will generate a register for every signal that gets assigned a value inside it, and that signals will keep the last value assigned to them inside a process.
You are also missing the Library ieee; statement at the top and a semicolon after buttonOut <= btnState.
Reading a button do need a debouncer.
Please take a look at:
VHDLWhiz generate statement
or
VHDLWhiz How to read a button in VHDL
Even though I see that you have already accepted Dimitris' answer, I can add that your code is almost right, you just need to toggle on the falling edge of of the latch instead of setting it to '1' as you do.
Try
if(rising_edge(CLK)) then
lastButtonState <= buttonState;
if(buttonState='0' and lastButtonState='1') then
btnState <= not btnState;
end if;
end if;
buttonOut <= btnState -- etc...
You don't need to initialize anything to '0' but you DEFINITELY need a switch debouncer as lukipedio said otherwise your toggle will not be consistent.
If you think about it, what you're doing is putting a "clock divider" on your lastButtonState register by toggling in order to set the btnState register at half the "frequency" of lastButtonState, which is what you want.
BTW, if you switch your toggling condition to
(buttonState='1' and lastButtonState='0')
then it will toggle on the rising edge of lastButtonState, in other words it will be toggle-on-press instead of toggle-on-release.
I'm trying to make a Blink-LED program for a Lattice MachXO3L breakout board. I believe I have the internal-oscillator set up, I just don't know how to connect to its output and make use of it, I get errors when I try. This is on a breakout board which has an LED and a switch. It should oscillate at 1Hz when the switch is flipped one way, and be off when the switch is flipped the other way.
I'e read the PLL usage guide and searched for answers on the internet. I believe I'm close, and just hung up on some syntax issue due to being new to VHDL & FPGAs. Basically, my main code is the 'process and all code below it. Anything above that is basically stuff from the PLL usage guide.
library ieee;
use ieee.std_logic_1164.all;
library machxo3l;
use machxo3l.all;
entity led_blink is
port (
i_switch_1 : in std_logic;
o_led_1 : out std_logic;
i_clock : in std_logic;
osc_int : out std_logic
);
end led_blink;
architecture rtl of led_blink is
COMPONENT OSCH
-- synthesis translate_off
GENERIC (NOM_FREQ: string := "12.09");
-- synthesis translate on
PORT ( STDBY:IN std_logic;
OSC:OUT std_logic);
END COMPONENT;
attribute NOM_FREQ : string;
attribute NOM_FREQ of OSCHinst0 : label is "12.09";
constant C_CNT_1HZ : natural := 6000000;
signal R_CNT_1HZ : natural range 0 to C_CNT_1HZ;
signal R_1HZ : std_logic := '0';
begin
OSCHInst0: OSCH
-- synthesis translate_off
GENERIC MAP(NOM_FREQ => "12.09")
-- synthesis translate on
PORT MAP (STDBY => '0',
OSC => osc_int
);
p_1HZ : process (i_clock) is
begin
if rising_edge(i_clock) then
if R_CNT_1HZ = C_CNT_100HZ-1 then
R_1HZ <= not R_1Hz;
R_CNT_1HZ <= 0;
else
R_CNT_1HZ <= R_CNT_1HZ + 1;
end if;
end if;
end process;
osc_int <= i_clock;
o_led_1 <= R_1HZ when (i_switch_1 = '0') else not R_1HZ;
end rtl;
If I try and assign osc_int to the sensitivity list of the p_1Hz process, I get an error stating that I can not read from an output.
Just a side-note in case other viewers get confused like me, driving i_clock from osc_int appears illogical, because it uses an assignment that seems to suggest the reverse occurs osc_int <= i_clock. Correct me if I'm wrong, but it's assigning an input, to an output, which appears confusing to non-hdl programmers because the direction is decided by the input/output types, rather than the assignment operator itself.
When I do this (link i_clk to osc_int), it saves without giving me errors, it isn't until I try to synthesize the code that it says there are multiple non-tristate drivers for i_clock. The only way I can imagine this being true is if the 'port' from the 'component' section named OSC, being mapped to osc_int, creates two driving signals both linked to i_clock in that single osc_int <= i_clock; statement. But if that's true, how would you access the clock's output at all?
If I just remove the osc_int <= i_clock statement, it works, just with the LED constantly-on/constantly-off, not oscillating/constantly-off.
The clock generated came from inside the OSCH component. Then you don't need any i_clock to achieve what you want. The output of the internal oscillator is the OUT port of the OSCH component.
you can try this :
entity led_blink is
port (
i_switch_1 : in std_logic; -- from the input switch : OK
o_led_1 : out std_logic -- to the blinking led : OK
);
end led_blink;
architecture rtl of led_blink is
COMPONENT OSCH
-- synthesis translate_off
GENERIC (NOM_FREQ: string := "12.09");
-- synthesis translate on
PORT ( STDBY:IN std_logic;
OSC:OUT std_logic);
END COMPONENT;
attribute NOM_FREQ : string;
attribute NOM_FREQ of OSCHinst0 : label is "12.09";
constant C_CNT_1HZ : natural := 6000000;
signal R_CNT_1HZ : natural range 0 to C_CNT_1HZ := 0;
signal R_1HZ : std_logic := '0';
begin
OSCHInst0: OSCH
-- synthesis translate_off
GENERIC MAP(NOM_FREQ => "12.09")
-- synthesis translate on
PORT MAP (STDBY => '0',
OSC => osc_int -- <= this is the 12.09MHz internal clock from the internal oscillator
);
p_1HZ : process (osc_int) is
begin
if rising_edge(osc_int) then
if R_CNT_1HZ = C_CNT_100HZ-1 then
R_1HZ <= not R_1Hz;
R_CNT_1HZ <= 0;
else
R_CNT_1HZ <= R_CNT_1HZ + 1;
end if;
end if;
end process;
o_led_1 <= R_1HZ when (i_switch_1 = '0') else '0';
end rtl;
I need to generate a constant high signal pulse_out to output to an oscilloscope.
I tried letting the output signal pulse_out <='1' and this didnt work either. I believe due to my knowledge that an output port signal needs to be driven by a clock.
I also tried using combinational logic and letting a two signals that were opposite of each other make a new signal by using AND,OR and this did not work either.
I know it is a stupid question, but I am stumped.
Any sample code of showing how to output a constant high value of '1' would be great.
I agree with Josh's comment on checking your pin numbers and pin report to make sure you are driving the pin you think you are. Setting a signal to '1' should drive the pin high.
You can double check it too by driving a divided clock out and give yourself an edge to trigger a scope on.
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;
ENTITY test IS
PORT (i_clk : IN std_logic;
i_reset : IN std_logic;
o_scope : OUT std_logic
);
END test;
ARCHITECTURE behv OF test IS
SIGNAL scope : std_logic;
BEGIN
p1 : PROCESS (i_clk, i_reset)
BEGIN
IF i_reset = RESET_LEVEL THEN
scope <= '0';
ELSIF clk'event AND clk = '1' THEN
scope <= NOT scope;
END IF;
END PROCESS p1;
o_scope <= scope;
END behv;
I am currently in the middle of a project where I am attempting to design a single cycle cpu. I am doing this without any pipe-lining, since that would greatly add to the complexity of the design. I am simply taking baby steps as I learn this. I find myself stuck at this portion where I am simply attempting to code a Program Counter(PC) using previously made components.
The model of my design looks like this picture here. Sorry, no idea why it came out dark, but if you click on it it shows correctly. The PC and theMUX are both 32 bit components, so I assume the adder is as well.
Here is the code I have been given, my implementation begins at the begin statement on line 41.
Pay no attention to it for now, its just a bunch of random gibberish I was attempting.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
---------------------------------------------------
entity pc_update is
port( clk: in std_logic; -- clock
incH_ldL: in std_logic; -- increment PC = PC + 4 when high,
-- load PCInput when low
PCInput: in std_logic_vector(31 downto 0); -- external input for PC
InstrAddr: out std_logic_vector(31 downto 0) ); -- instruction address
end entity pc_update;
----------------------------------------------------
architecture pc_update_arch of pc_update is
component register32 is
port( clr: in std_logic; -- async. clear
clk: in std_logic; -- clock
ld: in std_logic; -- load
D: in std_logic_vector(31 downto 0); -- data input
Q: out std_logic_vector(31 downto 0) ); -- data output
end component register32;
component mux2to1_32 is
port( sel: in std_logic; -- selection bit input
X0: in std_logic_vector(31 downto 0); -- first input
X1: in std_logic_vector(31 downto 0); -- second input
Y: out std_logic_vector(31 downto 0)); -- output
end component mux2to1_32;
signal PC_current: std_logic_vector(31 downto 0); -- the current state of PC reg
signal PC_add_4: std_logic_vector(31 downto 0); -- output from the adder
signal PC_next: std_logic_vector(31 downto 0); -- output from the MUX
begin
PC: register32 Port Map(
clk, Q, clr, D);
MUX: mux2to1_32 Port Map(
X0,sel,X1,Y);
process (incH_ldL)
begin
wait until (clk = '1');
if incH_1dL = '0' then
InstrAddr <= X0;
else InstrAddr <= X1;
end if;
end process;
end architecture pc_update_arch;
I am fairly new to this so I have only a faint idea of how signals work, and no idea how I am supposed to implement the components into the design. I am also confused that I wasnt asked to build the adder ahead of time. Is it now necessary to use it as a component im guessing?
Anyhow, I have attempted different things that stumbled upon searching, such as the port mapping you see. But I always get some sort of error, currently the error im receiving is that objects Q, clr, and D are used but not declared. How do I declare them?
If I get rid of those statements, the error simply repeats for objects X0, X1, and Y.
Any help in the right direction would be greatly appreciated. Thanks guys!
Also, just in case you need them,
The register
library ieee ;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
---------------------------------------------------
entity register32 is port(
clr: in std_logic; -- async. clear
clk: in std_logic; -- clock
ld: in std_logic; -- load
D: in std_logic_vector(31 downto 0); -- data input
Q: out std_logic_vector(31 downto 0) ); -- data output
end entity register32;
----------------------------------------------------
architecture register32_arch of register32 is
begin
process(clk, clr)
begin
if clr = '1' then
q <= x"00000000";
elsif rising_edge(clk) then
if ld = '1' then
q <= d;
end if;
end if;
end process;
END register32_arch;
and the MUX
library ieee ;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
---------------------------------------------------
entity mux2to1_32 is
port( sel: in std_logic; -- selection bit input
X0: in std_logic_vector(31 downto 0); -- first input
X1: in std_logic_vector(31 downto 0); -- second input
Y: out std_logic_vector(31 downto 0)); -- output
end entity mux2to1_32;
----------------------------------------------------
architecture mux2to1_32_arch of mux2to1_32 is
begin
Y <= X1 when (SEL = '1') else X0;
end architecture mux2to1_32_arch;
EDIT
Ok, NO idea if I did this correctly, but I rewrote the portmaps. I was having errors of port names (sel, clk, X0, X1..etc) being "used but not initialized. So that is why clr, clk and ld have initial values. Once again, no idea if that is correct, but it made the errors go away. I also realized I never added the register32 and mux2to1_32 VHDL files to my project, and after doing so got rid of the other errors I was having.
So as stands, the code compiles, I have included in the project a VWF simulation file for testing, but I KNOW the results are gonna be incorrect.
I dont know everything that is wrong yet, but I know I need to do something with PC_add_4. THis value needs to basically be (PC_current + 4), but Im not sure how to do this.
Here is the updated portion of code(everything else is the same)
PC: register32 Port Map(
clr => '0',
clk => '0',
ld => '1',
Q => PC_current,
D => PC_next
);
MUX: mux2to1_32 Port Map(
sel => incH_ldL,
X0 => PCInput ,
X1 => PC_add_4,
Y => PC_next
);
process (incH_ldL)
begin
if (rising_edge(clk)) then
if incH_ldL = '0' then
InstrAddr <= PC_current;
else InstrAddr <= PC_add_4;
end if;
end if;
end process;
And, in case they help, my list of errors..im guessing the pin related errors are because I dont have any hardware assignments made yet.
Warning (10541): VHDL Signal Declaration warning at pc_update.vhd(38): used implicit default value for signal "PC_add_4" because signal was never assigned a value or an explicit default value. Use of implicit default value may introduce unintended design optimizations.
Warning (10492): VHDL Process Statement warning at pc_update.vhd(61): signal "clk" is read inside the Process Statement but isn't in the Process Statement's sensitivity list
Warning: Output pins are stuck at VCC or GND
Warning: Design contains 34 input pin(s) that do not drive logic
Warning: Found 32 output pins without output pin load capacitance assignment
Warning: The Reserve All Unused Pins setting has not been specified, and will default to 'As output driving ground'.
Warning: Can't generate programming files because you are currently using the Quartus II software in Evaluation Mode
Warning: No paths found for timing analysis
Critical Warning: No exact pin location assignment(s) for 66 pins of 66 total pins
SECOND EDIT
So yeah I fixed up my code by adding
PC_add_4 <= (PC_current + 4 );
after the port mappings, and adding "clk" to the process sensitivity list.
However my waveforms in my simulation are still wrong I believe, as shown here.
It appears to be treating incH_lDL as a clear signal, rather than simply passing PCInput to InstrAddr. This is most likely due to my setting of it to a default '0' in the port map. I did this earlier because it was giving me "used but not declared" errors. Ill try messing with it and post my findings.
Third EDIT
I have edited my code as such:
process (incH_ldL, clk)
begin
if rising_edge(clk) then
if (incH_ldL = '0') then
InstrAddr <= PCInput ;
else InstrAddr <= PC_add_4;
end if;
end if;
end process;
My simulation now shows that when incH_lDL = 0, PCInput is loaded into InstrAddr, however, when incH_lDL = 1, it simply loads the value '4', and doesnt increment at the start of every clock cycle like its supposed to...I need to make use of PC_current, but I am not sure how....sicne you cant assign one signal to another like "PC_current <= PCInput". I will try some more things,in the mean time, any pointers would be greatly appreciated.
FOURTH EDIT
THanks to anyone still reading this, and bearing through all the reading.
I have attempted to use PC_next and PC_current in my implementation, but have run into "multiple constant drivers for net "PC_next" errors.
MY process code:
process (incH_ldL, clk, PC_next, PC_current)
begin
if rising_edge(clk) then
if (incH_ldL = '0') then
PC_next <= PCInput;
else PC_next <= PC_add_4;
end if;
end if;
InstrAddr <= PC_current;
end process;
I am aware that this error comes when these assignments are made within loops? I am truly at a loss here at what to try next.
Your port maps in the first code need to be ported to signals. You are placing the port names of the components in the port map, which is incorrect. What you would like to do is create signals that can connect those components, and place them in the port map fields instead (to match the connections in your image).
I have a very simple operator problem in VHDL. I try to compare some inputs with logical operators but get an error message...
entity test is
port (
paddr : in std_logic_vector(15 downto 0);
psel : in std_logic;
penable : in std_logic;
pwrite : in std_logic
);
end entity test;
signal wrfifo_full : std_logic;
process (paddr, psel, penable, pwrite, wrfifo_full) is
begin
if (((paddr(8 downto 2) = "1000000")) and (psel and penable) and (pwrite and not(wrfifo_full))) then
dt_fifo_wr_i <= '1';
else
dt_fifo_wr_i <= '0';
end if;
end process;
Unfortuantely, I get then the following error message:
if (((paddr(8 downto 2) = "1000000")) and (psel and penable) and
(pwrite and not(wrfifo_full))) then
| ncvhdl_p: *E,OPTYMM (hdl/vhdl/test.vhd,523|43): operator argument type mismatch
87[4.3.3.2] 93[4.3.2.2] [7.2]
Anyway sees the problem?
Cheers
psel, penable, pwrite and wrfifo_full are all std_logic.
In vhdl, to write the test they way you have, they would need to be boolean.
Instead write the code so that you are comparing their values to 1 or zero.
(paddr(8 downto 2) = "1000000" and
psel = '1' and penable ='1' and
pwrite = '1' and wrfifo_full = '0')
As George said, you have to currently convert all your std logics to booleans.
In VHDL-2008 however, there is a new conditional operator (??) which is applied implicitly to statements such as yours, which means they will work as you hoped. You'll have to enable VHDL-2008 support on you compiler (or whinge at your supplier to get with the times :)
This book is a good read on all the new bits that VHDL2008 gives us:
VHDL-2008 Just the new stuff
Section 4.4 covers the conditional operator