Verilog - Inverter with X input - input

I have an inverter with X input when my testbench start. So my output is X too.
Can i force my output is 1 or 0 when my input is X?
Thank you.

Sure you can. If your inverter is a module instance, simply force the wire that is tied to the output. If it is just an assign statement, just force the wire that's being assigned to.
module tb();
reg l_a;
wire l_q;
invtr i0(.q(l_q), .a(l_a));
initial begin
$vcdpluson;
#10;
force l_q = 1'b0;
#10;
release l_q;
#10;
l_a = 1'b0;
#10;
l_a = 1'b1;
#10
$finish;
end
endmodule
module invtr (output wire q,
input wire a);
assign q = ~a;
endmodule
The force of the output happens at time 10ns and the release happens at time 20ns. During this time the value is 0.

No.
An X value is the result of an error; it does not represent any well-defined value. Performing any kind of operation on such a value will also result in an unpredictable value -- another X.
You will need to figure out what is causing this error and fix it.

Not possible for an inverter. Providing an input X will always inherently give an output X.

Related

Verilog: Use of register: When are the values actually updated?

When exactly are the variables inside an always-block in Verilog updated?
E.g. if the reg C is changed multiple times in an always-block: does the value of it always change? Or is the value only "physically written" to the reg at the end of the always-block?
Would it be better to use an extra intermediate register which is only actualized at the end of the always-block? Would it make any difference?
reg C;
always #(*)
C = 0;
C = A;
C = 1;
C = B;
end
Other example:
If I have a module with an always block as follows, could the multiple assignments of the output exhibit sort of a glitch, where the output quickly goes to 0 before getting the value of B? Does it make a difference if I use blocking (=) or non-blocking (<=) assignments?
module example1 (output C, input A, input B);
always #(*)
begin
C = 1’b0;
if (A==1)
C = B ;
end
endmodule
Example with intermediate register to avoid unwanted change of the output.
module example1 (output C, input A, input B);
reg intermediateReg;
always #(*)
begin
intermediateReg = 1’b0;
if (A==1)
intermediateReg = B ;
end
C <= intermediateReg;
endmodule
In the examples you provided the code behaves identically to the 'c' code. The variable gets re-assigned new values and the last one wins. In verilog this is true for blocking (=) or non-blocking (<=) assignments, but not for the mix of them.
As in 'c' it is up to the compiler optimization technique. It can eliminate unneeded assignments, so only the last one is relevant.
In your first example the value of 'C' will be 'B' at the end of the block. The value of 'C' in the second example will either be 0 or B, depending on A.
Now, for the purpose of a simplicity of explanation, mixing of blocking and non-blocking assignments will cause the last 'non-blocking' assignment win. The reason is that all nba's are executed after the block is finished.
always #(*) begin
C <= A;
C = B;
end
The value of C will be A at the end of the simulation cycle.
As for the question about using intermediate values, there is no difference. You use them as needed. The simulation compiler or synthesis will optimize your code in any case. The last example is absolutely normal, except that it does not change anything at all. It behaves the same way as this, which is more explicit and more readable in my opinion. The only problem is that you incorrectly use nba assignments int combinational logic (which i fixed).
always #(*)
begin
if (A==1)
C = B ;
else
C = 1'b0;
I guess there is another silent question in your post, will the intermediate value cause events on 'C', the answer in this case is no. There will be no events produced by the always block till it finishes its execution (or till it hits a delay or starts waiting on an event). So, only the last value is relevant.
In a testbench code you can see a situation like that:
always #* begin
C = A;
C = B;
#5 C = D;
end
In the above case The value of C will become B. The execution of the always block will stop for #5 delays. During that time other blocks will see the value B. In #5 ticks, the value will be changed to D.
If you want to know what blocking and non-blocking assignments do in standard Verilog (like you would have in simulation), you can easily look that up.
If you're talking about hardware, the type of hardware you get will depend on what's in the sensitivity list, not type type of assignments you use. The type of assignment will affect the combinational logic that is synthesized from your code. Assuming you aren't doing anything unsynthesizable, the logic you get should be equivalent to what the Verilog standard specifies but won't be a 1:1 direct mapping of your code.
So, no, adding intermediates won't necessarily help with glitches in the hardware. There will be other code and timing specifications, etc. for dealing with stuff like that.

Verilog d flipflop circuit testing

I'm trying to construct a structural implementation of a circuit that consists of a d flipflop, it has inputs x and y, x and y are exclusive or'd and that result is exclusive or'd with the current state, and used as the input to the d flip flop. and it'll use the result state from the flipflop in the next run, etc. But I'm not too sure how to construct it.
The circuit looks like so:
module dff(D,clk,q);
input D,clk;
output q;
reg q;
always # (posedge clk)
begin
q<=D;
end
endmodule
I'm pretty sure the d flip flop code is correct but when I try to test this my d and state values are just x for some reason. When I put in different x and y values in my testbench nothing happens, "state" and "d" just always says it has value "1'hx" in the simulation. Why is this happening and how do I actually assign an value to them?
All signals in verilog simulation are initialized to 'x'. So are the values of A and D. Your second xor is applied to xoy ^ A. Since A is x, the result of this xor is always x. you need to break this loop, as oldfart suggested.
The usual way for doing it is to introduce a reset in the flop, synchronous or asynchronous. Here is an example of a synchronous reset flop:
always #(posedge clk)
if (reset)
q <= 0;
else
q <= D;
So, now, if you set your reset to '1' for at least one posedge of clk and then set it to '0', you will break the loop by pushing a non-'x' value in the data path.
You do not clear your D-FF. The output is X at the start and as you use that in a feedback loop it stays X.
This: wire state=1'b0; does not clear you FF. You have to clear 'q'.

verilog assigning to same variable not working

I am having a strange problem with Verilog HDL.
I found in my code that if I multiply a variable by two, but then
assign that value to the same variable, it gets all messed up.
Sometimes, the simv program even crashes. I originally needed to do this,
because I had a for loop for shifting or rotating a certain amount. But,
then I found that not only shifting the same variable did not work, but
also, addition, subtraction, multiplication, or division does not work either.
So in my code example, if you set a to 16'b0001_0000_1010_0101, and b to 3,
then you get an output of 16'b0000_0000_0000_0000. Just note that I am ignoring b for now... I should get 16'b0010_0001_0100_1010... but something is going wrong.
So, this is my code file test.v:
// ALU module.
module test(in1, in2, out1);
input [15:0] in1;
input [15:0] in2;
output reg [15:0] out1;
// Variables for shifting right and for rotating left or right.
reg [15:0] shiftedValue;
always#(in1, in2)
begin
assign shiftedValue = in1;
assign shiftedValue = shiftedValue * 2;
assign out1 = shiftedValue;
// This display value is correct!
// but it's still wrong in the test bench.
$display("out1 == %b", out1);
end
endmodule
module testStim;
reg [15:0] a;
reg [15:0] b;
wire [15:0] c;
// create ALU instance.
test myTest(a, b, c);
initial
begin
a = 16'b0001_0000_1010_0101;
b = 3;
#10
$display("op1In == %b, op1Out == %b", a, c);
$finish;
end
endmodule
This is the output after running simv (I stripped out the erroneous garbage...):
out1 == 0010000101001010
op1In == 0001000010100101, op1Out == 0000000000000000
Thanks,
Erik W.
You have done what is called as procedural continuous assignment.
The difference between regular continuous assignments and procedural continuous assignments is this:
Continuous assignment can only drive wire/net data type. Procedural assignment can drive only reg data type and not nets.
Continuous assignment should appear outside procedural blocks(always, initial etc), while latter must be inside procedural blocks.
Continuous assignment executes each time the right hand side expression changes. Procedural assignment depends on sensitivity list of always block.
As soon as the always block ends, the effect of assign statement is removed. You must add deassign statement to retain the values (which I think is not the real intent) or Just remove assign statement from the code. As shown below:
shiftedValue = in1;
shiftedValue = shiftedValue * 2;
out1 = shiftedValue;
More information about assign, deassign is available at this, this and this links.

Verilog module for a smoke detector and a buzzer

I have Altera DE2-115 FPGA and I try to self-learn Verilog. I decided to make a smoke detector and whenever it smells smoke the buzzer rings (the smoke detector outputs a digital signal).
Here is my trial :
module fire(flag,clock,reset,fire,fire_state,firealarm);
input clock, reset, flag, fire;
output [2:0] fire_state;
output firealarm;
wire fire;
reg [2:0] fire_state;
assign firealarm = (fire_state == 1) ? (flag ? 0 : 1) : 0;
always # (posedge clock)
fire_state<= fire ? 1: 0;
end module
But it doesn't run and I think there are a lot of logic errors in this code, any help please? :)
endmodule is one word, you need to remove the space.
Almost all simulators these days support verilog-2001 or greater so I would encourage the use of the modern port style (ANSI) and not the old verilog 1995 style.
Your port list goes from:
module fire(flag,clock,reset,fire,fire_state,firealarm);
input clock, reset, flag, fire;
output [2:0] fire_state;
output firealarm; wire fire;reg[2:0] fire_state;
to :
module fire(
input clock,
input reset,
input flag,
input fire,
output reg [2:0] fire_state,
output firealarm
);
I have placed each port on a new line with it direction, this makes it much easier to maintain code, it also make it a lot more readable and therefore minimises the chance of typos in connections.
You have used this syntax a lot (flag?0:1), where you using a boolean to select a boolean there is no need to do this and makes it more difficult to read. If you need to invert it then is a bitwise invert (~). However it is not clear what you are using flag for.
for comparrisons and assignments you should be including the width.
assign firealarm = (fire_state == 3'b1)? (~flag) : 1'b0;
This could also be written out in a combinatorial always block:
always #* begin
if (fire_state==3'b001) begin
firealaram = ~flag;
else begin
firealaram = 1'b0;
end
end
fire is 1 bit, fire_state is 3 bits.
always # (posedge clock) begin
fire_state <= {2'b0, fire};
end

Output skew when using clocking blocks

I am using a clocking block in my interface for signal aliasing. I want to concatenate some of the bits together to form a bus, and then drive this bus from my driver. So, for example:
interface bus_intf (clk);
input logic clk;
logic[1:0] x_lsb;
logic[1:0] x_msb;
clocking driver_bus #(posedge clk)
default input #1step output #0;
output x_bus = {x_msb, x_lsb};
endclocking
endinterface
Now the problem with this is, in one of my assertions, I need to read bus_intf.driver_bus.x_bus. As stated in the SV manual, an output variable from a clocking block should not be read by the testbench, and if it is, then simulator spits out an error (or warning in my case).
So I modified the interface:
interface bus_intf (clk);
input logic clk;
logic[1:0] x_lsb;
logic[1:0] x_msb;
clocking driver_bus #(posedge clk)
default input #1step output #0;
inout x_bus = {x_msb, x_lsb};
endclocking
endinterface
The problem now is, in my waveform I see two signals being created - x_bus and x_bus__o. I understand why Questasim did this - it is to separate the inout declaration so I can view both versions.
However, the problem now is all my clocking drive is delayed by one clock cycle! so x_bus__o which is connected to the DUT is one clock cycle later than x_bus. This is inspite of me explicitly stating that output skew is #0.
Any idea why this happens? Am I doing something wrong or have I misunderstood?
I've put your code on EDAPlayground and tried it out. It seems to be working as expected. Here's my test harness:
module top;
bit clk;
always #1 clk = ~clk;
bus_intf busif(clk);
initial begin
#busif.driver_bus;
$display("time = ", $time);
busif.driver_bus.x_bus <= 'hf;
repeat (2)
#(negedge clk);
$display("time = ", $time);
busif.driver_bus.x_bus <= 'ha;
#100;
$finish();
end
always #(busif.x_lsb)
$display("time = ", $time, " x_lsb = ", busif.x_lsb);
always #(busif.x_msb)
$display("time = ", $time, " x_msb = ", busif.x_msb);
endmodule
The link is here if you want to try it online: http://www.edaplayground.com/x/Utf
If I drive x_bus at a posedge, then the value will be written immediately, as would be expected due to the #0 output delay. If I drive x_bus at a negedge (or at any other time aside from a posedge), then it will wait until the next posedge to drive the value. I see this behavior regardless of whether x_bus is declared as output or inout.
Check to see when you are scheduling your writes; this might be the reason you see some delays on your waves.
When you have bidirectional flow through a clocking block, the signal from the verification to the hardware and back has to go through two virtual D-FFs. So the original observation is correct. The input of 1-step is one D-FF to the design; then the return is one more D-FF back appearing 0ns (i.e., just after the clock). Clocking blocks are not useful in the situation of a signal that requires a single-cycle turn-around, and for that reason, you avoid them if that is a requirement. For most designs, it is simply not necessary. Monitors will observe the signals with a pipeline delay of one cycle, which is generally not a problem.