module johnson #(parameter N=8)
(output logic [N-1:0] q, input logic clk,reset);
always_ff #(posedge clk,posedge reset)
if(reset)
q<=0;
else
q<={~q[0],q[N-1:1]};
endmodule
Above is the systemverilog HDL for an 8-bit Johnson counter. I read from a textbook that it has large number of unused states that form a counter of their own i.e a parasitic state machine. What exactly is this parasitic state machine?
The problem here is that if this circuit ended up entering one of the unused states for some reason you would be stuck in a loop then never returns to one of the used states. This counter has the following states:
00000000
10000000
11000000
11100000
11110000
...
00001111
00000111
00000011
00000001
If a cosmic ray hits your chip and flips one of the bits then you could end up with states that don't exist in normal operation:
00010000
10001000
11000100
11100010
11110001
01111000
10111100
....
The only way to get back to normal is by asserting reset. You have two options to deal with this: either add a bunch of logic to detect the situation, or assume that a bit randomly flipping isn't going to happen. I would say that you don't need to worry about it unless that flipped bit is going to launch a missile.
Related
I need to check the value of a signal after a certain amount of time a clock edge occurs. For example, I want to check that if signal b asserts to high 1ps after posedge clock occurs.
Does SVA provide a syntax for this?
system-verilog-assertions were not intended for use as gate-level timing checks. Verilog already provides a number of built-in and optimized timing checks like $setuphold and $skew. See section 31. Timing checks in the IEEE 1800-2017 SystemVerilog LRM.
Timing checks are usually expressed as limits—either assertion happens at least 1ps after the clock edge, or at most 1ps after the clock edge. Also, must b be asserted after every clock edge? Regardless of the answers to these questions, it's possible to use SVA to model timing check, but you will have to manually create equations based on the actual requirements. For example
property p;
realtime timestamp;
#(posedge c) ($rose(a), timestamp = $realtime) |=>
#(posedge b) $realtime - timestamp < 1ps;
endproperty
I am looking for some intuitive understanding of systemverilog method of waiting for certain signal on the interface for 1) capturing transaction in a monitor, or 2) driving a transaction in response to some signal from DUT. Let's assume that DUT is asserting ready signal and driver has to drive two data beats (values of 1 and 2) back to back while asserting valid signal so that DUT would know when to capture data.
There are two methods of waiting for the ready single from the DUT that I know of; 1) one is iff conditioned clock event, and the other is 2) consuming clock while some signal is not true (e.g., ready is low). The testbench code can be found EDA playground (line 37 of my_driver.sv).
The first method is using #(posedge dut_vif.clock iff(dut_vif.ready == 1));
and the second method is using while( ! dut_vif.ready) #(posedge dut_vif.clock); and there is single clock difference between two methods as shown in the waveform. My best understanding is --
#(posedge dut_vif.clock iff(dut_vif.ready == 1));
This method is waiting for the clock rise event 'on the condition' of ready == 1. Therefore, data and valid are driven high on 25ns.
while( ! dut_vif.ready) #(posedge dut_vif.clock);
On the other hand, this statement means that simulation should consume clock while ready is low. However this interpretation and the actual behavior of systemverilog is very different. At 15ns, ready signal goes high and the valid and data are driven at the same cycle. My understanding is that at 15ns, the ready should be still captured as low by the testbench, and simulation should consume one clock. Therefore, the second method should behave just like the first method.
Can I get some interpretation on how to make sense of this difference?
I am attaching waveform here.
The issue is because of hidden delta delay inside the call to get_next_item() Even though the time is still at 15, counter and thus ready now have their new values after returning from the call. Using iff gives you a clearer sampling of values w.r.t the clock edge. It also avoids problems when !ready is x because that evaluates to false.
#(event iff (expression));
is equivalent to
do #event; while (!expression);
not
while (!expression); #event;
as Dave mentioned at here, maybe he forget it. That's why you missed one clock cycle.
I am confused about the usage of statements always_ff and always_latch.
The former would be used as:
always_ff # (posedge clk)
begin
a <= b;
end
while the latter:
always_latch
begin
a <= b;
end
The first is activated just by the positive edge of the clock and, coupled with nonblocking assignment, produces a FF.
The always_latch is obviously thought to represent a latch, but then why use a nonblocking assignment?
Wouldn't it be better using an always_comb with blocking assignments?
By using always_latch or always_ff a designers intent to infer a latch or a sequential logic respectively, but if the logic is not correct software tools can warn the designer that the intended hardware logic is not inferred properly.
eg:
always_ff # (posedge clk or negedge rst)
begin
if (!rst)
a <= '0;
end
For the above code the designer intended to get only a sequential logic and not a latch but a latch would be generated in actual (Any static tool will generate a warning message as "Latch will be inferred for the logic")
Similarly for the below code the designers intent is to infer a hardware latch so tool will(understand your logic better) and won't report it.
always_latch
begin
if (rst)
a <= b;
end
Latch is a sequential logic which works on levels of clocks instead of clock edges.
In general best practice is to use Non-blocking assignments for sequential logic and blocking assignments for combinatorial logic which is explained in detail under Section 5.0
Verilog coding guidelines of Nonblocking Assignments in Verilog Synthesis, Coding Styles That Kill!
Guideline #2: When modeling latches, use nonblocking assignments.
From IEEE Std 1800-2012, section "9.2.2.3 Latched logic always_latch procedure":
The always_latch construct is identical to the always_comb construct
except that software tools should perform additional checks and warn
if the behavior in an always_latch construct does not represent
latched logic, whereas in an always_comb construct, tools should check
and warn if the behavior does not represent combinational logic.
The code example in the Std shows the always_latch using a non-blocking assignment.
I've been reading through UVM: illegal combination of driver and procedural assignment warning and paper attached in answer.
(Please consider paper linked in the question mentioned)
However drivers are implemented to drive reset values on interface signals instead of on clocking block signals, the clock is not guaranteed to be running at reset.
So how can I go about this scenario if interface signals are declared wires.
for e.g.
consider the code in linked question. General scenario would be
#(vif.cb);
vif.cb.opcode <= value;
This is correct even if opcode is declared net in interface cause clocking block will take care of correct assignment. However I can't say
#(vif.rst);
vif.cb.opcode <= init_value;
since I can't guarantee clock at reset. To accommodate this I'll have to change clock generation strategy.
Neither can I say
vif.opcode <= init_value;
cause its illegal to use procedural assignment with net type signals
The other way is gating signals declared as net with reset but I think for that I'll have to declare temporary signals in interface. Can anyone elaborate how can I achieve driving nets at reset ?
While it's illegal to assign nets from procedural code, it's legal to force values onto them. You can do the following:
#(negedge vif.rst);
force vif.opcode = 0;
Bonus: IMO you shouldn't have opcode defined as a wire. The illegal combination of procedural and continuous driver warning is wrong. The SV 2012 standard clearly states in 14.16.2 Driving clocking output signals:
It is possible to use a procedural assignment to assign to a signal associated with an output clockvar. When
the associated signal is a variable, the procedural assignment assigns a new value to the variable, and the
variable shall hold that value until another assignment occurs (either from a drive to a clocking block output
or another procedural assignment).
I have trouble understanding the following assembly code which is used to add two integers using registers. It's not a very cumbersome question, just that I lack any good reference to learn the syntax. If you can provide me with the insight line by line. I would be extremely grateful.
MOV R1, #100
MOV R2, #100
MOV (R1), #50
ADD R2,(R1)
I get the first two lines which will store number 100 in the given registers, I just don't get the purpose of using brackets in next two lines.
And this is not homework, Just a question to clarify the theory behind it.
Question is what are the values of R1, R2 after the instructions have been executed.
I found the following explanation on another website, which helped me a lot to understand the use of brackets. I believe it would be very clarifying for other people too, so I will post it below:
Lets analyze this program:
MOV AX, 47104
MOV DS, AX
MOV [3998], 36
INT 32
... The first instruction, MOV AX, 47104, tells the computer to copy the number 47104 into the location AX. The next instruction, MOV DS, AX, tells the computer to copy the number in AX into the location DS. The next instruction, MOV [3998], 36 tells the computer to put the number 36 into memory location 3998. Finally, INT 32 exits the program by returning to the operating system.
Before we go on, I would like to explain just how this program works. Inside the CPU are a number of locations, called registers, which can store a number. Some registers, such as AX, are general purpose, and don't do anything special. Other registers, such as DS, control the way the CPU works.
DS just happens to be a segment register, and is used to pick which area of memory the CPU can write to. In our program, we put the number 47104 into DS, which tells the CPU to access the memory on the video card.
The next thing our program does is to put the number 36 into location 3998 of the video card's memory. Since 36 is the code for the dollar sign, and 3998 is the memory location of the bottom right hand corner of the screen, a dollar sign shows up on the screen a few microseconds later.
Finally, our program tells the CPU to perform what is called an interrupt. An interrupt is used to stop one program and execute another in its place. In our case, we want interrupt 32, which ends our program and goes back to MS-DOS, or whatever other program was used to start our program.
We can see from this example that the use of brackets resulted in inputting a value into a memory location, and not into a register. Lately, this value was read by the video card to display a symbol on the screen.
Credits to the writer on: http://www.swansontec.com/sprogram.html