0% found this document useful (0 votes)
8 views30 pages

T01 Verilog Tutorial

This document provides a tutorial on Verilog simulation toolflow for a course, detailing the setup and usage of various tools such as Synopsys DC, VCS, and Cadence Encounter. It includes examples of implementing a Greatest Common Divisor (GCD) algorithm in Verilog, along with test harnesses and simulation commands. Additionally, it covers configuration file creation for the mkasic.pl script and the structure of a beta micro-architecture.

Uploaded by

xiadongseu
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views30 pages

T01 Verilog Tutorial

This document provides a tutorial on Verilog simulation toolflow for a course, detailing the setup and usage of various tools such as Synopsys DC, VCS, and Cadence Encounter. It includes examples of implementing a Greatest Common Divisor (GCD) algorithm in Verilog, along with test harnesses and simulation commands. Additionally, it covers configuration file creation for the mkasic.pl script and the structure of a beta micro-architecture.

Uploaded by

xiadongseu
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 30

Tutorial #1

Verilog
Simulation
Toolflow
v
vc s mips.
%
imv
% ./s RPP &

% vcs

6.884 – Spring 2005 02/09/05 T01 – Verilog 1


6.884 Toolflow For Lab 1 and 2
Assembly
StdCell Verilog
Source
Library Source
Code

Synopsys DC Synopsys VCS SMIPS Assembler

Verilog
StdCell Func Test
Gate
Library Sim Inputs
Level

Cadence Encounter Synopsys VirSim Test Scripts

Timing
Test
Area
Outputs
Power

6.884 – Spring 2005 02/09/05 T01 – Verilog 2


Tour of the 6.884 Athena Locker
To access the locker use setup 6.884
– /mit/6.884/tools
– /mit/6.884/doc
– /mit/6.884/examples

For those with access to the CAG network please


make use of the CAG infrastructure
– Use setup 6.884 (will setup tools needed for the course)
– Locker (partially) mirrored at /projects/assam/6.884
– CAG updates will probably lag a bit behind Athena

6.884 – Spring 2005 02/09/05 T01 – Verilog 3


Three Examples

GCD
Beta
Lab1

6.884 – Spring 2005 02/09/05 T01 – Verilog 4


Greatest Common Divisor

Control Unit
go A A B B out done
mux reg mux reg mux
sel en sel en B=0 A<B sel

zero? lt out
A_in
A
sub

B_in
B

6.884 – Spring 2005 02/09/05 T01 – Verilog 5


GCD Control Logic

out_mux_sel
while ( !done )

A_mux_sel

B_mux_sel
if ( A < B )

A_en

B_en

done
swap( A, B )
else if ( B != 0 ) Load 1 1 0 0 X 0
A=A–B
Swap 1 1 1 1 1 0
else
done = true Sub 1 0 1 X 0 0
endwhile Done 0 0 X X X 1

reg [5:0] ctrl_sig;


assign { A_en, B_en, A_mux_sel, B_mux_sel, out_mux_sel, done } = ctrl_sig;

always @(*)
begin
if ( !running ) ctrl_sig = 6'b11_00x_0; // Latch in A and B values
else if ( A_lt_B ) ctrl_sig = 6'b11_111_0; // A <= B and B <= A
else if ( !B_zero ) ctrl_sig = 6'b10_1x0_0; // A <= A - B and B <= B
else ctrl_sig = 6'b00_xxx_1; // Done
end

6.884 – Spring 2005 02/09/05 T01 – Verilog 6


GCD Test Harness

Control Unit
go A A B B out done
mux reg mux reg mux
sel en sel en B=0 A<B sel

zero? lt out

A_in
A
sub

B_in
B

6.884 – Spring 2005 02/09/05 T01 – Verilog 7


GCD Test
module gcd_test;
reg clock = 0; reg reset = 0; reg go = 0;
reg [15:0] A_in, B_in;

wire done; Harness


wire [15:0] Y;

always #10 clock = ~clock;


gcd_rtl gcd_unit( .clock(clock), .reset(reset), .go(go),
.A_in(A_in), .B_in(B_in), .done(done), .Y(Y) );

initial begin
$vcdpluson(0);
A_in = 27; B_in = 15; // Set defaults
$value$plusargs("a-in=%d",A_in); // Read in cmdline args
$value$plusargs("b-in=%d",B_in);

#5 reset = 1; #20 reset = 0; // Strobe reset signal


#20 go = 1; #20 go = 0; // Strobe go signal
end

always @( done ) begin


if ( done ) begin
#15;
Try to keep the Verilog
$display(" a-in
$display(" b-in
= %d", A_in );
= %d", B_in );
part of the test harness
$display(" gcd-out = %d", Y
$finish;
);
as simple as possible!
end
end

endmodule

6.884 – Spring 2005 02/09/05 T01 – Verilog 8


Building a GCD Simulator with VCS
% setup 6.884
Attaching 6.884 …
Running commands in /mit/6.884/.attachrc …
% vcs –PP +lint=all +v2k gcd_rtl.v
% ./simv
VCD+ Writer 4.4R10 Copyright 1993-2004 Synopsys Inc.
a-in = 27
b-in = 15
gcd-out = 3
$finish at simulation time 245
% ./simv +a-in=49 +b-in=28
VCD+ Writer 4.4R10 Copyright 1993-2004 Synopsys Inc.
a-in = 49
b-in = 28
gcd-out = 7
$finish at simulation time 225
% vcs –RPP &

6.884 – Spring 2005 02/09/05 T01 – Verilog 9


Viewing Waveforms with VirSim

Open up a
waveform
viewer

Browse Select
the signals
module for
hierarchy display

6.884 – Spring 2005 02/09/05 T01 – Verilog 10


Viewing Waveforms with VirSim

6.884 – Spring 2005 02/09/05 T01 – Verilog 11


Using Test Scripts
% vcs –PP +lint=all +v2k gcd_rtl.v
% vmodel-tester.pl –v ./simv gcd-test.dat

* Verilog model = ./simv


* Test data file = gcd-test.dat
* Running tests
+ Testing a-in=27 b-in=15 gcd-out=3
+ Testing a-in=21 b-in=49 gcd-out=7
+ Testing a-in=25 b-in=30 gcd-out=5
+ Testing a-in=19 b-in=27 gcd-out=1
+ Testing a-in=40 b-in=40 gcd-out=40
+ Testing a-in=250 b-in=190 gcd-out=10
+ Testing a-in=5 b-in=250 gcd-out=5
+ Testing a-in=0 b-in=0 gcd-out=0

*** PASSED ***

6.884 – Spring 2005 02/09/05 T01 – Verilog 12


Using the mkasic.pl Script
gcd/ gcd/
mkasic.pl gcd_behavioral/
verilog/ vcs/
gcd_behavioral.v vcstest/
gcd_rtl.v gcd_rtl/
config/ vcs/
gcd_behavioral.cfg vcstest/
gcd_rtl.cfg
tests/
gcd-test.dat

% cp –r /mit/6.884/examples/gcd
% cd gcd
% ./mkasic.pl –v config/gcd_rtl.cfg vcs
% ./mkasic.pl –v config/gcd_behavioral.cfg vcs
% ./mkasic.pl –v config/gcd_rtl.cfg vcstest
% ./mkasic.pl –v config/gcd_behavioral.cfg vcstest

6.884 – Spring 2005 02/09/05 T01 – Verilog 13


Writing Config Files for mkasic.pl
#-------------------------------------------------------------------------
# General configuration options

package general;
$outputDir = "gcd_rtl"; # Dir for all generated product
$verilogSrcDir = "verilog"; # Dir where all verilog source is located
$toplevelSource = "gcd_rtl.v"; # Verilog src file w/ toplevel module
$toplevelModule = "gcd_test"; # Name of toplevel verlog module

#-------------------------------------------------------------------------
# VCS - Synopsys Verilog compiler

package vcs;
$simName = "gcd-rtl"; # Name to use for the VCS simulator
$cmdLineOptions = ""; # Any additional VCS compiler options

#-------------------------------------------------------------------------
# Test

package vcstest;
$inputDir = "tests"; # Dir containing test inputs
@testList = ( "gcd-test.dat" ); # A list of test inputs
$cmdLine = "vmodel-tester.pl -v __SIMNAME__ __TESTINPUT__";

return 1; # Return true for mkasic.pl

6.884 – Spring 2005 02/09/05 T01 – Verilog 14


Beta Micro-Architecture
ILL
XAdr OP JT

PCSEL 4 3 2 1 0 Step 1: identify memories


PC 00
1 Step 2: identify datapaths
A Instruction
Memory
What’s left is random logic …
D
+4

Ra: <20:16> Rb: <15:11> Rc: <25:21>


0 1 RA2SEL

2 + WASEL

XP 1
RA1 Register RA2
WD
1
PC
Rc: <25:21> WA
WA
File
0
RD1 RD2 WE WERF
Z
JT
C: SXT(<15:0>)
PC+4+4*SXT(C)
IRQ Z
ASEL 1 0 1 0 BSEL

Control Logic

PCSEL
RA2SEL A B
ASEL ALU WD R/W Wr
ALUFN
BSEL
WDSEL Data Memory
ALUFN Adr RD
Wr
WERF
WASEL
PC+4 1
0 1 2 WDSEL
2
Main Datapath
6.884 – Spring 2005 02/09/05 T01 – Verilog 15
module pc

PC Dpath
(
input clk,
input reset, // forces PC to 0x80000000
input [2:0] pcsel, // selects source of next PC
input [15:0] offset, // inst[15:0]
input [31:0] jump_addr, // from Reg[RA], used in JMP instruction
output [31:0] branch_addr, // send to datapath for LDR instruction
output [31:0] pc, // used as address for instruction fetch
output [31:0] pc_plus_4 // saved in regfile during branches, JMP, traps
);

reg [31:0] pc;


wire [30:0] pcinc;
wire [31:0] npc;

assign pcinc = pc + 4;
assign pc_plus_4 = {pc[31],pcinc};

// Branch address = PC + 4 + 4*sxt(offset)


assign branch_addr = {1'b0, pcinc + {{13{offset[15]}},offset[15:0],2'b00}};

assign npc = reset ? 32'h80000000 :


(pcsel == 0) ? {pc[31],pcinc} : // normal
(pcsel == 1) ? {pc[31],branch_addr[30:0]} : // branch
(pcsel == 2) ? {pc[31] & jump_addr[31],jump_addr[30:0]} : // jump
(pcsel == 3) ? 32'h80000004 :
(pcsel == 4) ? 32'h80000008 : // illop, trap
32'hXXXXXXXX; // catch errors...

always @( posedge clk )


pc <= npc;

endmodule

6.884 – Spring 2005 02/09/05 T01 – Verilog 16


Beta Register File
module regfile
(
input [4:0] ra1, // address for read port 1 (Reg[RA])
output [31:0] rd1, // read data for port 1
input [4:0] ra2, // address for read port 2 (Reg[RB], Reg[RC] for ST)
output [31:0] rd2, // read data for port 2
input clk,
input werf, // write enable, active high
input [4:0] wa, // address for write port (Reg[RC])
input [31:0] wd // write data
);

// The register file itself


reg [31:0] registers[31:0];

// read paths are combinational, register 31 is always zero register


assign rd1 = (ra1 == 5'b11111) ? 32'h00000000 : registers[ra1];
assign rd2 = (ra2 == 5'b11111) ? 32'h00000000 : registers[ra2];

// write port is active only when WERF is asserted


always @(posedge clk)
begin
if ( werf )
registers[wa] <= wd;
end

endmodule

6.884 – Spring 2005 02/09/05 T01 – Verilog 17


module datapath
(
input [15:0] inst, // constant field from instruction
input [31:0] rd1, // Reg[RA] from register file
input [31:0] rd2, // Reg[RB] from register file (Reg[RC] for ST)
input [31:0] pc_plus_4, // incremented PC
input [31:0] branch_addr, // PC + 4 + 4*sxt(inst[15:0])
input [31:0] mem_rd_data, // memory read data (for LD)
input asel, // select A operand for ALU
input bsel, // select B operand for ALU
input [1:0] wdsel, // select regfile write data
input [5:0] alufn, // operation to be performed by alu
output [31:0] wdata, // regfile write data (output of WDSEL mux)
output [31:0] mem_addr, // alu output, doubles as data memory address
output [31:0] jump_addr, // jump address (from Reg[RA])
output [31:0] mem_wr_data, // data memory write data (from Reg[RC])
output z // true if Reg[RA] is zero, used during branches
);

wire [31:0] alu_a; // A input to ALU


wire [31:0] alu_b; // B input to ALU

// compute A and B inputs into alu, also Z bit for control logic
dp_misc misc(asel,bsel,inst,rd1,rd2,branch_addr,
alu_a,alu_b,jump_addr,mem_wr_data,z);

// where all the heavy-lifting happens


dp_alu alu(alufn,alu_a,alu_b,mem_addr);

// Mux to select regfile write data from PC+4, alu output, and memory data
dp_wdata_mux wdata_mux(wdsel,pc_plus_4,mem_addr,mem_rd_data,wdata);

endmodule

6.884 – Spring 2005 02/09/05 T01 – Verilog 18


Beta Control Signals
ILL
XAdr OP JT

PCSEL 4 3 2 1 0 Step 1: identify memories


PC 00
1 Step 2: identify datapaths
A Instruction
Memory
What’s left is random logic …
D
+4

Ra: <20:16> Rb: <15:11> Rc: <25:21>


0 1 RA2SEL

2 + WASEL

XP 1
RA1 Register RA2
WD
1
PC
Rc: <25:21> WA
WA
File
0
RD1 RD2 WE WERF
Z
JT
C: SXT(<15:0>)
PC+4+4*SXT(C)
IRQ Z
ASEL 1 0 1 0 BSEL

Control Logic

PCSEL
RA2SEL A B
ASEL ALU WD R/W Wr
ALUFN
BSEL
WDSEL Data Memory
ALUFN Adr RD
Wr
WERF
WASEL
PC+4 1
0 1 2 WDSEL
2
Main Datapath
6.884 – Spring 2005 02/09/05 T01 – Verilog 19
Beta Control Signals

6.884 – Spring 2005 02/09/05 T01 – Verilog 20


module control( ... );

// Control ROM
reg [15:0] ctl;
always @(*)
Beta Control Unit
begin

if (interrupt)
ctl = 16'bx_100_1xx_xxxxxx_00_0;
else
case (inst[31:26])
// Label control signal vector here ...
default: ctl = 16'bx_011_1xx_xxxxxx_00_0; // illegal opcode
6'b011000: ctl = 16'bx_000_001_00xxx0_10_0; // LD
6'b011001: ctl = 16'bx_000_x01_00xxx0_10_1; // ST
6'b011011: ctl = 16'bx_010_0xx_xxxxxx_00_0; // JMP
6'b011101: ctl = 16'b1_001_0xx_xxxxxx_00_0; // BEQ
6'b011110: ctl = 16'b0_001_0xx_xxxxxx_00_0; // BNE
6'b011111: ctl = 16'bx_000_010_011010_10_0; // LDR
...
6'b111100: ctl = 16'bx_000_001_10xx00_01_0; // SHLC
6'b111101: ctl = 16'bx_000_001_10xx01_01_0; // SHRC
6'b111110: ctl = 16'bx_000_001_10xx11_01_0; // SRAC
endcase

end

// We now use the local control signal vector to create the


// appropriate named control signals.
assign werf = ~ctl[0];
assign mem_we = !reset & ctl[0];
assign wdsel = ctl[2:1];
assign alufn = ctl[8:3];
assign bsel = ctl[9];
assign asel = ctl[10];
assign wa = ctl[11] ? 5'b11110 : inst[25:21];
assign pcsel = ((ctl[14:12] == 3'b001) & (ctl[15] ^ z)) ? 3'b000 : ctl[14:12];

assign ra2 = ctl[0] ? inst[25:21] : inst[15:11];


endmodule

6.884 – Spring 2005 02/09/05 T01 – Verilog 21


module beta
(
Putting It
input
input
input
clk,
reset,
irq,
All Together
output [31:0] inst_addr, // address of instruction to be fetched
input [31:0] inst_data, // instruction returning from memory
output [31:0] mem_addr, // address of data word to be accessed
input [31:0] mem_rd_data, // read data returning from memory
output mem_we, // memory write enable, active high
output [31:0] mem_wr_data // memory write data
);

// ... declare a bunch of internal signals here ...

// Control logic, reg file address generation


control ctl(reset,irq,inst_addr[31],z,inst_data[31:0],
alufn,asel,bsel,pcsel,ra2,wa,wdsel,werf,mem_we);

// PC Datapath
pc pc(clk,reset,pcsel,inst_data[15:0],jump_addr,branch_addr,
inst_addr,pc_plus_4);

// Register file
regfile regfile(inst_data[20:16],rd1,ra2,rd2,clk,werf,wa,wdata);

// Main datapath
datapath dp(inst_data[15:0],rd1,rd2,pc_plus_4,branch_addr,mem_rd_data,
asel,bsel,wdsel,alufn,
wdata,mem_addr,jump_addr,mem_wr_data,z);

endmodule

6.884 – Spring 2005 02/09/05 T01 – Verilog 22


Building Beta + Running Programs
% setup 6.884
% setup 6.004
% vcs –PP +lint=all +v2k beta.v
% uasm2vmh.pl self_test.uasm self_test.vmh
% ./simv +exe=self_test.vmh
*** PASSED ***

% ./mkasic.pl –v config/beta.cfg vcs


% ./mkasic.pl –v config/beta.cfg mktests
% ./mkasic.pl –v config/beta.cfg vcstest

Use different config files for different design


points – for example, try out different adder
implementations or synthesis constraints and
modular testing
6.884 – Spring 2005 02/09/05 T01 – Verilog 23
Lab1
Implement a 2 stage
pipelined processor
which supports SMIPS
ISA subset
– The SMIPS Processor
Spec is on the website
– Feel free to grab some
code from the Beta
implementation, but then
again the Beta code is not
always the best approach

6.884 – Spring 2005 02/09/05 T01 – Verilog 24


Lab1
Pipelined
Datapath

6.884 – Spring 2005 02/09/05 T01 – Verilog 25


Lab1 Test Harness

iaddr
instr tohost
fromhost
addr
wen mips_cpu
write_data
read_data

clk reset interrupt

6.884 – Spring 2005 02/09/05 T01 – Verilog 26


Lab1 Test Harness
`include "mips_cpu.v"

module mips_tester;
reg clk = 0; // Clock to core.
reg reset = 0; // Reset signal.
reg int_ext = 0; // Interrupt signal.

reg [7:0] fromhost = 8'b0; // Control reg to CPU.


wire [7:0] tohost; // Control reg from CPU.

wire [31:0] addr; // Data address.


wire wen; // Write enable.
wire [31:0] read_data; // Read data back to CPU.
wire [31:0] write_data; // Write data from CPU.
wire [31:0] iaddr; // Fetch address.
wire [31:0] inst; // Instruction.

always #5 clk = ~clk; // Clock generator (10ns clock period)


reg [ 1023:0 ] exe_filename;

mips_cpu mips(clk, reset, int_ext, fromhost, tohost,


addr, wen, write_data, read_data, iaddr, inst);

memory mem(clk, addr, wen, write_data, read_data, iaddr, inst);

...

6.884 – Spring 2005 02/09/05 T01 – Verilog 27


Lab1 Test Harness
...

initial
begin
$vcdpluson(0);

if( $value$plusargs( "exe=%s", exe_filename ) )


$readmemh( exe_filename, mem.m );
else begin
$display( "ERROR: No executable specified! (use +exe=<filename>)" );
$finish;
end

#0 reset = 1; #16 reset = 0; // Strobe reset


#10000; // Safety net to catch infinite loops
$display("*** FAILED ***");
$finish;
end

// Stop running when tohost changes.


always @(tohost) begin
case (tohost)
8'd0: ;
8'd1: begin $display("*** PASSED ***"); #20 $finish; end
default: begin $display("*** FAILED ***"); #20 $stop; end
endcase
end

endmodule

6.884 – Spring 2005 02/09/05 T01 – Verilog 28


Building Tests with smips-testbuild

SMIPS SMIPS SMIPS Verilog


Assembly gcc Object ld Elf
elf2vmh Memory
File File Binary Dump
(.S) (.o) (.vmh)

% smips-testbuild –vmh –smips self_test.S –o self_test.vmh


% mips2stage +exe=self_test.vmh
*** PASSED ***

% ./mkasic.pl config/mips2stage.cfg mktests


% ./mkasic.pl config/mips2stage.cfg vcstest

* Running tests on mips2stage/vcs/mips2stage simulator


+ [ PASSED ] simple_test.vmh
+ [ PASSED ] self_test.vmh

6.884 – Spring 2005 02/09/05 T01 – Verilog 29


Final Notes
Tools must be run either on Athena/Linux or CAG
– 38-301 is open 24 hours a day
– smips-testbuild should be working this afternoon
– CAG toolflow not quite setup yet

Lab is due at the start of class on Friday, Feb 18


– Write lots of tests (self_test is not enough!)
– We will email more information on exact collection procedure

Online resources
– Links to various Verilog whitepaper and references
– First chapter of Sutherland’s logical effort book

Office hours
– Tuesday + Thursday, 5:30pm – 7:00pm, 38-301

6.884 – Spring 2005 02/09/05 T01 – Verilog 30

You might also like