Week 6

Report
ECE 551
Digital System Design & Synthesis
Lecture 06
Loops
Non-synthesizable Constructs
File I/O
Topics


FOR Loops in non-testbench modules
Review
 Invalid/non-synthesizable hardware
 Testbench output methods

File I/O
2
For Loops In Hardware

Can use fixed-length for loops in modules
reg [15:0] countmem [0:7];
integer i;
always @(posedge clk) begin
for (i = 0; i < 8; i = i + 1) begin
countmem[i] <= countmem[i] + 1’b1;
end
end

These loops are unrolled prior to synthesis
 That’s why they must be fixed in length!
 Using integer because i is not actually synthesized
 Example creates eight 16-bit incrementers.
3
For Loops In Hardware

Using a For loop to design a variable size
decoder
parameter NUM_BITS = 16;
reg [(NUM_BITS – 1):0] decoded;
integer i;
always @(coded_in) begin
for (i = 0; i < NUM_BITS; i = i + 1) begin
decoded_out[i] = 1’b0;
end
decoded_out[coded_in] = 1’b1;
end
Parameter values are fixed from compile/elaboration time
Yes, this synthesizes
4
Behavioral Verilog Pitfalls

Behavioral Verilog gives us more flexibility than
Structural or RTL

This extra flexibility also makes it easier for us to
write descriptions that do not synthesize.

The next few slides cover a few things that
people commonly try to do that cannot be
synthesized.
5
Variable-Size For Loops

Using a for loop to design a variable size
bitmask generator
input [4:0] mask_size
reg [31:0] mask;
integer i;
always @(mask_size) begin
mask = 32’b0;
for (i = 0; i < mask_size; i = i + 1) begin
mask[i] = 1’b1;
end
end
Cannot synthesize variable values in loop control, because
they cannot be unrolled before Synthesis.
This does not synthesize, but might work in simulation!
6
Instantiating in an Always Block

Cannot synthesize (or simulate):
module bad(input a, b, c, output d);
always@(a,b,c)
if (c)
and(d, a, b);
else
or(d, a, b);
endmodule
 Conceptually, why is this a problem?

Later we will learn about generate-if statements,
which allow us to do something similar to this.
7
Cannot Detect x or z

Cannot Synthesize:
module find_x(input a, output b);
always@(a)
if (a === x)
b = 1’b1;
else
b = 1’b0;
endmodule
8
Cannot Detect x or z

Cannot Synthesize:
module find_x_z(input a, output d);
always@(a)
case (a)
1’bx : d = 1’b1;
1’bz : d = 1’b1;
default : d = 1’b0;
endcase
endmodule
 What if we had used casex? What would have been
synthesized?
10
Feedback In Combinational Logic

What happens
here?
// update the state
always @(posedge clk) begin
if (rst) begin
state <= 1’b0;
count <= 8’d0;
end else state <= next;
end

How can we fix it?
// find next state and
// count the 3’b101 values
always @(input, count) begin
if (input == 3’b101) begin
count = count + 1;
next = 1’b1;
end else begin
next = 1’b0;
end
end
11
Fixing The Example
// update the state and count
always @(posedge clk) begin
if (rst) begin
state <= 1’b0;
count <= 8’d0;
end else begin
// find next state and
state <= next;
// count the 3’b101 values
count <= nextcount; always @(state, input, count) begin
end
if (input == 3’b101) begin
end
nextcount = count + 1;
next = 1’b1;
end else begin
nextcount = count;
next = 1’b0;
end
end
12

We’ll cover a few more examples of code that
doesn’t synthesize later in the semester
13
Simulation I/O

Modelsim Lists and Waves
 Waves visually appealing
 Convenient, but constrained formats

Display/Strobe/Monitor
 Provide results to standard output
 Flexible text formats
 Sampling issues (Verilog Event Queue)

File I/O
 Good for archiving results
 Flexible text formats
 Useful for self-checking testbenches
 Sampling issues (Verilog Event Queue)
14
Display Functions in Detail

$display (and $write)
 $display adds newline, $write does not
 Occurs along with other active events, when encountered
initial #5 $display ("a = %h, b = %b", a, b);

$strobe
 Similar to $display, but displays data at the end of the current
simulation time (i.e. after all events at that simulation cycle have
been processed) – Region 4 Event
initial forever @(negedge clock)
$strobe ("Time=%t data=%h", $time, data);

$monitor
 Displays data at end of current simulation time, whenever a variable
in the argument list changes
initial $monitor ("Time=%t data=%h", $time, data);
15
Interesting Format Specifier: %m



Displays the hierarchical name of the module
calling the $display function
Useful when there are multiple instantiations of a
module to tell which instance caused the display
Doesn’t take a parameter
$display(“%m:
x=%b y=%b”, x, y);
16
%m Example [1]
module mexample();
wire out0, out1;
reg [3:0] in;
a a0(out0, in[2], in[0]);
a a1(out1, in[2], in[1]);
initial
$monitor("%m: out0=%b out1=%b in=%b", out0, out1, in[2:0]);
initial begin
for (in = 0; in < 8; in = in + 1) #5;
end
endmodule
module a(output reg out, input a, b);
always @(a, b) begin
out = a & b;
$display("%m: out=%b
a=%b b=%b", out, a, b);
end
endmodule
17
%m Example [2]

Simulation results:
…
#
#
#
#
#
#
#
#
#
#
#
#
#
…
mexample: out0=0 out1=0 in=010
mexample.a0: out=0
a=0 b=1
mexample: out0=0 out1=0 in=011
mexample.a0: out=0
a=1 b=0
mexample.a1: out=0
a=1 b=0
mexample: out0=0 out1=0 in=100
mexample.a0: out=1
a=1 b=1
mexample: out0=1 out1=0 in=101
mexample.a0: out=0
a=1 b=0
mexample.a1: out=1
a=1 b=1
mexample: out0=0 out1=1 in=110
mexample.a0: out=1
a=1 b=1
mexample: out0=1 out1=1 in=111
// in=011
// in=100
// in=101
// in=110
// in 111
18
File I/O – Why?


If we don’t want to hard-code all information in the
testbench, we can use input files
Help automate testing
 One file with inputs
 One file with expected outputs

Can have a software program generate data
 Create the inputs for testing
 Create “correct” output values for testing
 Can use files to “connect” hardware/software system
19
Opening/Closing Files

$fopen opens a file and returns a descriptor
 Syntax: integer desc = $fopen(filename, type);
 If file can’t be opened, returns a 0.
 Use $ferror to determine cause.

Can specify a mode (r, w, a+, etc) – see standard.

If no mode is specified, $fopen opens the file for
writing and returns a “multi-channel” descriptor
 integer fd = $fopen(“filename”, “r”);
 integer mcd = $fopen(“filename”);
 Can write to multiple multi-channel files simultaneously




using bit-wise OR ( | ) of the descriptors
Can only have 31 multi-channel files open at any time
Easier to have “summary” and “detailed” results
STDIN, STDOUT, STDERR are pre-opened
$fclose closes the file: $fclose(fd);
20
Writing To Files

Display statements have file equivalents
 $fdisplay()
 $fmonitor()



 No limit on number of $fmonitor tasks
$fstrobe()
$fwrite()
 $display without a newline
These system calls take the file descriptor as the
first argument
$fdisplay(fd, “out=%b in=%b”, out, in);
21
Reading From Files

Read a binary file: $fread(destination, fd);
 Can specify start address for loading into arrays
 Can specify a number of locations to load into array
 Returns number of bytes read, or 0 on error

Formatted reading: $fscanf(fd, format, args);
 Very similar to C equivalent

Reading characters/lines: $fgetc, $fgets
 Can use $sscanf after $fgets

Other commands given in standard
22
Examples of Reading from Files
reg [20:0] myreg; reg [7:0] character; reg [12*8:1] str
reg [7:0] mem [15:0]; reg [3:0] a, b;
integer code, start = 10, count = 20;
integer fd = $fopen(“my_file”);
character= $fgetc (fd); // returns -1 on error
code = $fgets ( str, fd );
code = $sscanf(str, “%d %d \n", a, b);
code = $fscanf(fd, “%d %d \n", a, b);
code = $fread( myreg, fd);
code = $fread( mem, fd);
// reads binary data
code = $fread( mem, fd, start, count);
// See 17.2 of standard for more details
23
Loading Memory Data From Files






Can read values from text file into a “memory”
 THIS IS NOT SYNTHESIZABLE
$readmemb(“filename”, memname [, start [, stop]]);
 Reads binary (plain-text) numbers from text file
$readmemh(“filename”, memname [, start [, stop]]);
 Reads hexadecimal (plain-text) numbers from text file
White space and comments are ignored
Can also specify addresses in the file itself
 @HH…HH
 Subsequent data will placed starting at the given address
Can fill memory in ascending or decending order by
changing the “start” and “stop” addresses
24
File I/O Example [1]
`timescale 1 ns/ 100 ps
module func_demo_nb_d0_clk_strobe;
reg [7:0] memory[0:255];
// 256 byte memory
integer descriptor;
// used with fopen
reg [7:0] address;
wire [7:0] data;
assign data = memory[address];
25
File I/O Example [2]
initial begin
//read binary data into locations 0 through 15 of memory
$readmemb("mem_data_in.txt", memory,0,15);
// read hex data into all 256 bytes - overwrites
$readmemh("mem_data_in_extra.txt", memory);
//open file; capture descriptor
descriptor = $fopen("mem_data_out.txt");
//close file at end of simulation run
#210 $fclose(descriptor);
$stop;
end
// Where might we use this type of file I/O?
26
File I/O Example [3]
//event control block
reg clk, reset;
initial begin
clk = 0; reset = 1;
$fstrobe(descriptor, "Time: %d Address: %d Data: %h",
$time, address, data);
#2 reset = 0; #3 ;
forever begin
#5 clk = 1;
$fstrobe(descriptor, "Time: %d Address: %d Data: %h",
$time, address, data);
#5 clk = 0;
end
end
27
File I/O Example [4]
// Dump of memory locations 'd0 through 'd20 in hexadecimal
always@(posedge clk or posedge reset) begin
// save in file mem_data_out.txt
if (reset)
address <= 0; //initialize address
else address <= address + 1; // advance address
end
endmodule
28
File I/O Example: Results
Memory Dump Using $fstrobe
Time:
Time:
Time:
Time:
Time:
Time:
Time:
Time:
Time:
Time:
Time:
0 Address:
10 Address:
20 Address:
30 Address:
40 Address:
50 Address:
60 Address:
70 Address:
80 Address:
90 Address:
100 Address:
0 Data: 01
1 Data: 02
2 Data: 04
3 Data: 08
4 Data: 10
5 Data: 20
6 Data: 40
7 Data: 80
8 Data: fe
9 Data: fd
10 Data: fb
Time:
Time:
Time:
Time:
Time:
Time:
Time:
Time:
Time:
Time:
110
120
130
140
150
160
170
180
190
200
Address:
Address:
Address:
Address:
Address:
Address:
Address:
Address:
Address:
Address:
11
12
13
14
15
16
17
18
19
20
Data:
Data:
Data:
Data:
Data:
Data:
Data:
Data:
Data:
Data:
f7
ef
df
bf
7f
cf
xx
16
xx
03
29
Testbench Example
module test_and;
integer file, i, code;
reg a, b, expect, clock;
wire out;
parameter CYCLE = 20;
and #4 a0(out, a, b);
// Circuit under test
initial begin : file_block
clock = 1’b0;
file = $fopen("compare.txt", “r” );
for (i = 0; i < 4; i=i+1) begin
@(posedge clock)
// Read stimulus on rising clock
code = $fscanf(file, "%b %b %b\n", a, b, expect);
#(CYCLE - 1)
// Compare just before end of cycle
if (expect !== out)
$strobe("%d %b %b %b %b", $time, a, b, expect, out);
end // for
$fclose(file); $stop;
end // initial
always #(CYCLE / 2) clock = ~clock; // Clock generator
endmodule
30
$finish(n), $stop(n)

Can print statistics about simulation at end



n=0:
n=1:
n=2:

prints nothing
prints simulation time, location
prints simulation time, location
and CPU utilization, some statistics
$finish causes simulation to stop
 Can cause tool to exit!

$stop causes simulation to suspend
 Simulation may be resumed manually
31
Review Questions




Why can’t the synthesizer process a “for” loop with
the bounds determined by an input value?
What is the difference between a latch and a flipflop? Why would we prefer one over the other?
Give two reasons why, in a testbench, we might
want to read from a file.
Why are Verilog file commands not synthesizable?
32

similar documents