You are on page 1of 66

Aebeedec Jan H.

Luciano BSECE-5

Engr. Gillert Bongcac CSC 127

Lab 1.1
In this lab, you will: Learn how to invoke a Verilog simulation Recognize common syntax errors Using a text editor, enter the following Verilog modules in separate files. Fix any syntax errors or warnings in the specification or any that you may introduce. Module HELLO initial $write(Hello World!\n); endmodule; module \HI; initial $write(Hi there!\n); end module;

hello.v

hi.v

Simulating each module separately using a single Verilog simulator, modelsim shows the following output: HELLO.v HI.v

Simulating both module together using the same Verilog simulator, modelsim shows the following output: vsim HI HELLO vsim HELLO HI

Questions: 1. Reverse the order in which the modules are specified on the command line. Are the results different? Answer: As the order of the way modules are specified is reversed, the results also show a reversed order which demonstrates how dependent the results are to the way the modules are sequenced. 2. Should you care? Answer: It depends on what is asked. Of course, if a specific order in the result is required, I should care.

Lab 1.2
In this lab, you will: Work with always blocks Work with initial blocks Use the $finish statement Enter the following Verilog module in a file: module HELLO; always begin end endmodule Simulate the module What is happening? Answer: Modelsim seems to display blank results infinitely. To help diagnose what is going on, add a $write statement inside the always block module HELLO; always begin $write(Hi!\n); end endmodule; Try to simulate the module again. Does the output confirm your suspicions? Answer: Yes it does! Adding the $write statement confirms that using the always statement indeed makes the output display results infinitely. In this case, it displays Hi. Edit the module and insert a $finish statement at the end of the always block. Simulate the module again. How is the simulation different? Answer: When the result is displayed, a dialog box appears automatically asking for one to finish the simulation or not. Edit the module and replace the always keyword with initial. The change turns the always block into an initial block. Simulate the module again

Is the simulation behavior different? Answer: Yes! It is different since the result only occurred once. Why did the simulation terminate by itself? Answer: The simulation terminated by itself automatically since the program requires only a single run and also, the $finish statement that pops out a dialog box allowing the user to choose for the simulation whether to finish or not, isnt present.

Lab 2.1
In this lab, you will: Learn to use various operators Witness the effect of operation sizes Use registers as targets of assignments Use concatenated assignment targets Learn the difference between a vector and a memory In directory ~/lab2.1, you will find a file name try.v. It contains an initial block with a single $write statement that is used to display the binary result of an expression. Replace the <expression> in the $write statement with each of the expressions on the next slide. What are the results you expect? Answer: Upon analysing the code, my expected results are listed below. Expression 1 1'b1 -1 -1'b1 1 << 1 1'b1 << 1 &4'b1111 &4'b111 |4'b0x10 |4'b0x00 4'b1111 & 1 ~4'b1000 !4'b1000 (1'b1) ? 1'bz : 3'bx (1'bx) ? 1'b1 : 1'b0 (!1'bx) ? 1'b1 : 1'b0 (2'b10 & 2'b01) ? 1'b1 : 1'b0 (2'b10 && 2'b01) ? 1'b1 : 1'b0 (1'bx == 1'bx) ? 1'b1 : 1'b0 1'bx === 1'bx) ? 1'b1 : 1'b0 {1'b1, {2'b01, 3'b1}} {3{1'b1, 2'bz}} Expected Result "00000000000000000000000000000001" "1" "11111111111111111111111111111111" "1" "00000000000000000000000000000010" "0" "1" "0" "1" "x" "00000000000000000000000000000001" "0111" "0" "00z" "x" "x" "0" "1" "x" "1" "101001" "1zz1zz1zz"

Modelsim displayed the following results: 1 # Result = 00000000000000000000000000000001 1'b1 # Result = 1 -1 # Result = 11111111111111111111111111111111 -1b1 # Result = 1 1<<1 # Result = 00000000000000000000000000000010 1b1<<1 # Result = 0 &4b1111 # Result = 1 &4b111 # Result = 0 |4b0x10 # Result = 1 |4b0x00 # Result = x 4b1111 & 1 # Result = 00000000000000000000000000000001 ~4b1000 # Result = 0111 !4b1000 # Result = 0 (1'b1) ? 1'bz : 3'bx # Result = 00z (1'bx) ? 1'b1 : 1'b0 # Result = x (!1'bx) ? 1'b1 : 1'b0 # Result = x (2'b10 & 2'b01) ? 1'b1 : 1'b0 # Result = 0 (2'b10 && 2'b01) ? 1'b1 : 1'b0 # Result = 1 (1'bx == 1'bx) ? 1'b1 : 1'b0 # Result = x (1'bx === 1'bx) ? 1'b1 : 1'b0 # Result = 1 {1'b1, {2'b01, 3'b1}} # Result = 101001 {3{1'b1, 2'bz}} # Result = 1zz1zz1zz Repeat the exercise, this time assigning the result of the expression to an 8-bit register, then displaying the contents of the register.

Displayed results in Modelsim: 1'b1 1'b1 -1'b1 -1'b1 1<<1 1b1<<1 &4b1111 &4b111 |4b0x10 |4b0x00 4b1111 & 1 ~4b1000 !4b1000 (1'b1) ? 1'bz : 3'bx (1'bx) ? 1'b1 : 1'b0 (!1'bx) ? 1'b1 : 1'b0 (2'b10 & 2'b01) ? 1'b1 : 1'b0 (2'b10 && 2'b01) ? 1'b1 : 1'b0 (1'bx == 1'bx) ? 1'b1 : 1'b0 (1'bx === 1'bx) ? 1'b1 : 1'b0 {1'b1, {2'b01, 3'b1}} {3{1'b1, 2'bz}} Explain any difference. Answer: The results in this simulation always contain 8-digits to it unlike the results in our first simulated program. It is expected for this to happen since an 8-bit register is used.

Lab 2.2
In this lab, you will: Learn how to use the if and case statements Learn how unknowns are handled in the if and case statements See how a case statement can be used to model an FSM

Operands != and !== designates different functions. The former indicates logical inequality while the latter denotes not synthesizable. In the code, instead of setting the register to 1b1 it was set to 1bx so, when the computer reads the if statement the set register will not be implemented and the rest of the preceding statements of the code will not displayed. The problem can simply be fixed by replacing the != by !==.

The Output in the transcript gives # R = c0

After 8 transitions, the machine is stuck in state 3b010. Why? Answer: Since state 3b010 is displayed repeatedly, the case statement will continue to display the last state if it doesnt find any matching state as the previous. The 8th transition in the program is terminated due to the if (i == 8) $finish block.

The case statement acts like the === operator since case does not ignore dont cares, but reads and outputs them instead.

What is the transition sequence? Why? Answer: In casez, during simulation, an inadvertent x signal in casez, will not be matched by a 0 or 1 in the case choice. For the first to the sixth transitions, operation goes from top to bottom, i.e. 001,100, 000, 010, x00, 0zz. In the 7th transition, state 3b0zz matches state 3b001 thus generating the next new state 3b100. In here, 3bxxx was ignored because, as aforementioned, casez ignores an x signal and does not take it as a dont care. Then 3b100 is compared and 8th state 3b000 is displayed. The program is thereafter terminated due to the if (i == 8) $finish block. casex statemement

What is the transition sequence? Why? Answer: In casex, the choices may contain z, x, or ? which are used as dont cares for comparison. Casex uses x as a dont care which can be used to minimize logic. The transition sequence is 001, 001, 001, In the comparison process during simulation, state 3bxxx outputs the new state 3b001 in the first transition. To find the next new state (second transition) 3b001 is then compared starting from the top case condition and satisfies 3bxxx, generating 3b001. This repeats until the 8th transition is reached and the program is terminated due to the if (i == 8) $finish block.

Lab 2.3

An always statement isnt valid in an initial statement since it signifies a free-running process and it is a concurrent statement that is continuously executed during simulation. An initial statement indicates a process executed exactly once making the two statements unsuitable and cannot be placed in a single Verilog code.

Walking Code generation

Modelsim simulation

ModelSim Simulation

Modelsim Simulation

Lab 2.4
In this lab, you will: Learn to recognize common syntax errors in functions and tasks Learn how to use functions and tasks Learn how arguments are passed to functions and tasks

syntax.v with correction

Modelsim Simulation

Lab 3.1
In this lab, you will: Learn how to use a waveform viewer Learn to use the # statement Learn how to use the @ statement Learn the difference between various sampling techniques Identify problems caused by event ordering and simulation startup

Simulating the model to verify that the correct waveform is generated,

Why is the message sequence different? Answer: The statement only monitors the positive change (or rising edge) of the waveform.

Why is the message sequence different? Answer: The statement only monitors the negative change (falling edge) of the waveform.

Why is the message sequence different? Answer: The message sequence is actually similar to the first simulation, always@(R).

Why are they different? Explain the differences. Answer: They are different because delay is introduced to register R. These delays are also placed in different orientations, resulting different results.

Lab 3.2
In this lab, you will: Learn how to single-step through a model execution Witness the sequential execution of parallel blocks Examine the sequence of event-driven simulation

Simuling model.v in Modelsim yields,

Lab 4
vave.v

ModelSim result:

Sample.v

ModelSim result:

Answer: The above waveform differs because of the delays that are placed in a different syntax of wave.v in lab 3.1

Lab 4.2
bug.v

ModelSim Result: *no errors were encountered.

bus.v

ModelSim Result:

Modified Verilog Module: bus.v

ModelSim Result:

*When wire [3:0] BUS; is replaced with wor [3:0] BUS: ModelSim result:

*When wire [3:0] BUS; is replaced with wand[3:0] BUS: ModelSim Result:

DELAYS WERE ADDED: #(3) were added: ModelSim result:

#(2,4) were added: ModelSim result:

#(2,4,6) were added: ModelSim result:

sample.v

ModelSim result:

Lab 5.1

adder.v

noop.v

sub.v

Instantiation

Simulation

The method of instantiation used is by position, it is done by placing the ports in exactly the same positions in the port lists of both the template and the instance. rules.v

It is observed that wire W can be readily connected to either input, output and inout of the lower-level module. R, on the other hand, can only be connected to the input of the lower level module and not to the output and inout. In connecting R to the output or inout of the lower-level module, one way not to cause any syntax errors is to pass the value of R to W through an assign statement. In this way R is connected to the lower-level module ports through W.

design.v

Original Output:

Modified design.v

Simulation shows a similar waveform, hence, the correctness is still verified.

Lab 5.2
inverter.v

testinv.v

Question: In compiling and simulating the 2 modules together, why is the order suddenly significant? The order of the modules is significant when both are compiled and simulated simultaneously because of timescale declarations on modules. The first module entered must contain the timescale declaration if it is the top module of the succeeding instantiated modules. Otherwise, if the top module doesnt declare one, even if lower modules contain timescales themselves, the simulation always fails. Table for various timescales on the tester and inverter modules:

Modified testinv.v

Running the simulation with the timescale pairs below, the first timescale shows the same reported delays as before while the second shows a different one. Instead of 3.6 s-2.2 s rise-fall, the result for the second timescale pair shows 3.6ns-2.2ns. Tester - 1ns/1ns - 1ps/1ps Inverter - 1ns/100p - 1ns/100ps

Modifying again by replacing the calls to the $realtime task by calls to the $time task:

Running the simulation with the timescale pairs below, the first timescale shows the same reported delays as before while the second still shows a different one. Instead of 3.6 ns-2.2 ns risefall, the result for the second timescale pair shows 4ns-2ns. This is because $time tasks only return integer values and not real ones. Tester - 1ns/1ns - 1ns/1ns Inverter - 1ns/1ns - 1ns/100ps

Lab 5.3
inverter.v

testinv.v

Simulation

Using parameter to declare rise and fall delay:

It was verified that they have the same output. Modifying the tester module to override the rise and fall delays, using the positional notation: INVERTER #(4.5, 1.6) DUT(...); With this modification, the delays of the inverter are now changed to 4.5-1.6 ns from 3.6-2.2 ns. Question: Is it possible to override only the fall delay parameter if it is declared second? It is possible to override only the fall delay parameter by using only one delay in the overriding inverter and declaring the fall delay parameter first in the inverter module. Hence, rule of thumb is simple: the first delay parameter to be declared in the inverter module will be the delay thats subject for overriding. Answer: Modifying the parameter override from positional to using a defparam statement (using the proper names for the parameters):

defpram DUT.RISE = 4.5, DUT.FALL = 1.6; The result shows the same overriding values. And changing the order in which parameters are declared doesnt show significant changes in the delays. Question: Can you specify an override value for rise-delay parameter only? For the fall-delay parameter only? How? Verify your hypothesis. Answer: Yes, we can override value for the rise-delay parameter only as well as for the fall-delay parameter only. As stated before, we use the positional notation of overriding in the tester module. Using positional notation, and a single value in its delay, the overridden delay parameter will depend on which parameter was declared first in the inverter module. Simply declare parameter for rise-delay first if you want it overridden. You do the same thing for the fall-delay parameter if you want fall-delay overridden. This order overrides the rise-delay:

This order overrides the fall-delay:

In the tester module, add 3 parameters defined, to 0.8, 1.0, 1.2 to represent scaling factors for best, typical, and worst-case operating conditions, respectively. The simulation looks like this: Hence, the correctness is still verified.

Lab 5.4
testnot.v

Simulation # Fall delay = 2.200 ns # Rise delay = 3.600 ns Like before, the simulation shows the same delay values. Modifying the timescale to 100ps/10ps gives different delay values: # Fall delay = 0.220 ns # Rise delay = 0.360 ns Question: How does that compare to using an inverter module rather than an inverter primitive? Answer: Using an inverter primitive inside the tester module makes the inverter totally dependent to the tester at the level of timescale. On the other hand, using a separate inverter module sets the inverters

timescale independent to that of the tester. Hence, even if the tester module timescale is modified as long as the inverter timescale is retained, the simulation will show no significant change in delay values Behavioral Description rfilebeh.v

Simulation

Gate Level Description rfileprm.v

Simulation

testdsgn.v

It was observed that the gate-level model was the easiest model to debug than the behavioural model. Both descriptions were simulated separately. Supposedly, both simulations must have a different CPU time required for simulation. The behavioral description is expected to have the fastest simulation time over the gate-level description using primitives. But eventually, no noticeable performance difference was observed. The difference might be rather easily viewed depending on the users level of knowledge about the software there might be a certain step to do it which was not specified in this exercise.

Question: 1. Which model was quickest to write/modify? Answer: The behavioral model was quickest to modify between the 2 descriptions because it only has short codes. 2. Which model simulated the fastest? Answer The Behavioral model is expected to be the fastest. sample.v

Simulation

S1: The machine scans for a sample every 10 ns during a transition. It reads a sample but waits for 10 ns before catching it. S2: The machine scans for a sample every 10 ns during a transition. It catches the current state of the input after 10ns. S3: The machine delays every input transitions every 10 ns. S4: The machine scans for a sample every 10 ns and catches it right then and there. S5: Similar to S4, but uses primitive buffer to sample the input.

Lab 6.1
monitor.v

Simulation:

$monitor used to emulate the displaying function

Simulation

Explain the differences in the reported changes. Answer: We can see an obvious difference between the 2 monitoring functions based on their simulations. Although both are the same in that both displays once every time R changes its value, they do not have the same level of sensitivity. The first one using a $display function inside an always block displays every time there is a single change in R value even the change occurs in the absence of delay. The one using $monitor inside the initial block displays only one value change per time delay and it is usually the last one. Replacing the $display statement with a $strobe statement made the function the same with the $monitor statement in the initial block. dumprom.v

rom.v

rom.dat

modified rom.v to set values for rom.dat

Simulation

dump2rom.v

Simulation

Why is the content of both ROMs identical? Answer: The ROMs in dump2rom.v are identical because both instantiates the same ROM module, rom.v which also contains only 1 file rom.dat that holds the ROM values. Override the ROM initialization file parameter of each ROM instance with different filenames. Create these new files, then simulate again. Verify that each ROM has the proper content.

rom1.v

rom2.dat

Simulation:

Lab 6.2
forever.v

Run your test procedure against each arbiter individually using the commands:

using arbiter1.v as the Design Under Test (DUT):

using arbiter2.v as the Design Under Test (DUT):

using arbiter3.v as the Design Under Test (DUT):

Which arbiter works? What is wrong with the arbiters that do not work? Answer: The first arbiter is the only arbiter that worked among the three. The second arbiter tested didnt pass the requirement that the grant assertion must particularly fall within 100ns. The last arbiter tested also failed because it didnt follow the requirement that grant desertion must particularly fall within 10ns. Their waveforms are shown below. Arbiter 1

Arbiter 2

Arbiter 3

Note: Register a monitors the correctness of the grant assertion, while register b monitors the correctness of the grant desertion.

You might also like