CS代考 CSE 141L: Introduction to Computer Architecture Lab

PolyPoint and the First Steps Towards Ubiquitous Localization

CSE 141L: Introduction to Computer Architecture Lab
SystemVerilog

Copyright By PowCoder代写 加微信 powcoder

Pat Pannuto, UC San SE 141L
CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others

Logistics Updates
Internal signups for CSE basement labs end today
Expect to post hours beginning of next week
Trickling in on Canvas now, but subject to change still…
CloudLabs is live
ModelSim is dead, long live Questa [but ModelSim is fine too]
When following tutorials, seems safe to s/ModelSim/Questa
Vocabulary
Labs -> Milestones + Final Report

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others
Logistics Update: Waitlists
24 people and counting who are in/finished 141 but waitlisted for 141L
This is too many to just let everyone in

If you are considering dropping this course, please do so ASAP

If you are far back on the waitlist for 141, then please make room in 141L
141 will be offered next quarter
(I’m teaching it)

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others
Synthesizable System Verilog 1 – Fundamentals

module adder( input [3:0] A, B,
output cout,
output [3:0] S );
wire c0, c1, c2;
FA fa0( A[0], B[0], 1’b0, c0, S[0] );
FA fa1( A[1], B[1], c0, c1, S[1] );
FA fa2( A[2], B[2], c1, c2, S[2] );
FA fa3( A[3], B[3], c2, cout, S[3] );

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others

What is SystemVerilog (SV)?
In this class and in the real world, SystemVerilog is a specification language, not a programming language.
Draw your schematic and state machines and then transcribe it into SV.
When you sit down to write SV you should know exactly what you are implementing.
We are constraining you to a subset of the language for two reasons
These are the parts that people use to design real processors
Steer you clear of problematic constructs that lead to bad design.

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others
[System]Verilog is a Hardware Description Language (HDL)
The other popular HDL is VHDL
An HDL is not a programming language — it is an HDL!

SystemVerilog is a new-ish improvement over Verilog
Technically, it’s a backwards-compatible superset
This can be troublesome, as Verilog is earlier to make mistakes in :/

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others
SV Fundamentals
What is System Verilog?
Data types
Structural SV
Combinational Logic
Sequential Logic

module adder( input [3:0] A, B,
output cout,
output [3:0] S );
wire c0, c1, c2;
FA fa0( A[0], B[0], 1’b0, c0, S[0] );
FA fa1( A[1], B[1], c0, c1, S[1] );
FA fa2( A[2], B[2], c1, c2, S[2] );
FA fa3( A[3], B[3], c2, cout, S[3] );

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others

Bit-vectors are the primary data type in Synthesizable SV
High impedance, floating
Unknown logic value
Logic zero

An X bit might be a 0, 1, Z, or in transition. We can set bits to be X in situations where we don’t care what the value is. This can help catch bugs and improve synthesis quality.
A bit can take on one of four values
In the simulation waveform viewer, Unknown signals are RED. There should be no red after reset.

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others

logic keyword denotes a hardware net that has a single driver but possibly multiple outputs
It can be combinational or sequential – other syntax will tell which
logic [15:0] instruction;
instruction

instruction

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others

wire keyword denotes a hardware net that has >=1 drivers, or that has unknown (or bi-) directionality
wire [15:0] bus_A;
wire [15:0] bus_B;
wire [ 7:0] small_net;

Absolutely no type safety when connecting nets!

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others

Bit literals
Binary literals
8’b0000_0000
8’b0xx0_1xx1
Hexadecimal literals
32’h0a34_def1
Decimal literals

Underscores
are ignored
Base format
(d,b,o,h)‏
Decimal number representing size in bits
We’ll learn how to actually assign literals to nets a little later

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others

SV Fundamentals
What is System Verilog?
Data types
Structural SV
Combinational Logic
Sequential Logic

module adder( input [3:0] A, B,
output cout,
output [3:0] S );
wire c0, c1, c2;
FA fa0( A[0], B[0], 1’b0, c0, S[0] );
FA fa1( A[1], B[1], c0, c1, S[1] );
FA fa2( A[2], B[2], c1, c2, S[2] );
FA fa3( A[3], B[3], c2, cout, S[3] );

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others

A SV module has a name and a port list

// HDL modeling of
// adder functionality
module adder( input [3:0] a_i,
input [3:0] b_i,
output cy_o,
output [3:0] sum_o );
Note the semicolon at the end of the port list!

Ports must have a direction and a bitwidth.
In this class we use _i to denote in port variables and _o to denote out port variables.

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others

A module can instantiate other modules

module adder( input [3:0] a_i, b_i,
output cy_o,
output [3:0] sum_o );
logic c0, c1, c2;
FA fa0( … );
FA fa1( … );
FA fa2( … );
FA fa3( … );

module FA( input a_i, b_i, cy_i
output cy_o, sum_o);
// HDL modeling of 1 bit
// full adder functionality

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others

Connecting modules

module adder( input [3:0] a_i, b_i,
output cy_o,
output [3:0] sum_o );
logic c0, c1, c2;
FA fa0( a_i[0], b_i[0], 1’b0, c0, sum_o[0] );
FA fa1( a_i[1], b_i[1], c0, c1, sum_o[1] );
FA fa2( a_i[2], b_i[2], c1, c2, sum_o[2] );
FA fa3( a_i[3], b_i[3], c2, cy_o, sum_o[3] );

Carry Chain

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others

Only connect ports by name and not by position.
Connecting ports by ordered list is compact but bug prone:
FA fa0( a_i[0], b_i[0], 1’b0, c0, sum_o[0] );

Connecting by name is less compact but leads to fewer bugs. This is how you should do it in this class. You should also line up like parameters so it is easy to check correctness.
FA fa0( .a_i(a_i[0])
,.b_i(b_i[0])
,.cy_i(1’b0)
,.cy_o(c0)
,.sum_o(sum_o[0])

Argument order does not matter when ports are connected by name – but don’t take advantage of this feature – makes it hard to detect missing parameters.

Connecting ports by name yields clearer and less buggy code. In the slides, we may do it by position for space. But you should do it by name and not position.

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others

SV Fundamentals
What is System Verilog?
Data types
Structural SV
Combinational Logic
Sequential Logic

module adder( input [3:0] A, B,
output cout,
output [3:0] S );
wire c0, c1, c2;
FA fa0( A[0], B[0], 1’b0, c0, S[0] );
FA fa1( A[1], B[1], c0, c1, S[1] );
FA fa2( A[2], B[2], c1, c2, S[2] );
FA fa3( A[3], B[3], c2, cout, S[3] );

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others

assign z_o = (x_i | y_i) & z_i;

very straightforward mapping to hardware
variables are names of wires; operators are gates
parse tree
tree of gates
Language-defined operators:
& is ‘AND’

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others
A module’s behaviour can be described in many different ways but it should not matter from outside
Example: mux4

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others

module mux4( input a_i, b_i, c_i, d_i,
input [1:0] sel_i,
output z_o );

logic t0, t1;

assign z_o = ~((t0 | sel_i[0]) & (t1 | ~sel_i[0]));
assign t1 = ~((sel_i[1] & d_i) | (~sel_i[1] & b_i));
assign t0 = ~((sel_i[1] & c_i) | (~sel_i[1] & a_i));

Using continuous assignments to generate combinational logic
The order of these continuous assign statements in the source code does not affect functionality – they are just specifying a bunch of gates – a combinational cloud.

Any time an input to the combinational cloud changes, it propagates through the cloud of gates and the outputs are updated. (Be careful not to create combinational cycles!)
A couple of combinational
trees that
connect to each

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others

should show parse tree turning into logic tree

// Four input multiplexer
module mux4( input a_i, b_i, c_i, d_i,
input [1:0] sel_i,
output z_o);
assign z_o = ( sel_i == 0 ) ? a_i :
( sel_i == 1 ) ? b_i :
( sel_i == 2 ) ? c_i :
( sel_i == 3 ) ? d_i : 1’bx;

If sel_i is X or Z, without the 1’bX condition, it would get d_i in behavioural simulation but maybe not in timing. Bad!

Having the 1’bx will help make sure your timing simulation looks the same as your behavioural.

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others

should show construction of tree

Using combinational always_comb or always @(*) block
module mux4( input a_i, b_i, c_i, d_i,
input [1:0] sel_i,
output logic z_o );
logic t0, t1;

always_comb // system verilog; replaces always @(*)
t0 = (sel_i[1] & c_i) | (~sel_i[1] & a_i);
t1 = ~((sel_i[1] & d_i) | (~sel_i[1] & b_i));
t0 = ~t0;
z_o = ~( (t0 | sel_i[0]) & (t1 | ~sel_i[0]) );

Within the always_comb block, the synthesis tool synthesizes the lines in order.
Each L-value (variable to the left of =) creates a name for the wire that is at the top of a logic tree. If a variable is assigned again (like t0), then the mapping is updated – no cycles are created.

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others

Should add “t0 pointer update” diagram.

always_comb permits more advanced combinational idioms
if (sel_i == 2’d0 )
z_o = a_i;
else if (sel_i == 2’d1)
z_o = b_i;
else if (sel_i == 2’d2)
z_o = c_i;
else if (sel_i == 2’d3)
z_o = d_i;
z_o = 1’bx;

always_comb
case ( sel_i )
2’d0 : z_o = a_i;
2’d1 : z_o = b_i;
2’d2 : z_o = c_i;
2’d3 : z_o = d_i;
default: z_o = 1’bX;

module mux4( input a_i,b_i,c_i,d_i
input [1:0] sel_i,
output logic z_o);
Good idea for avoiding behavioral versus timing mismatches.

If none of these match, behavioral will just use last value. Timing will give you an X probably.

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others

Synthesis of if/else
logic t0, t1, sel;

always_comb

t0 = t1+1;
t1 = t0+1;

Note: a mux is created for every L-value written by all branches of the if/else or case statement.

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others

Synthesis of if/else
logic t0, t1, sel;

always_comb
t0 = 1’b1;

t0 = t0+1;
t1 = t0+1;

Note: no L-value should be undefined on any path; behavior is undefined; Verilog will create a latch (ugh)!

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others

Synthesis of if/else
logic t0, t1, sel;

always_comb
t0 = 1’b1;

t0 = t0+1;

Is this example okay?

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others

What happens if the case statement is not complete?
module mux3( input a_i, b_i, c_i,
input [1:0] sel_i,
output logic z_o );

always @( * )
case ( sel_i )
2’d0 : z_o = a_i;
2’d1 : z_o = b_i;
2’d2 : z_o = c_i;
What have we created?
If sel = 3, mux will output
the previous value!

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others

What happens if the case statement is not complete?
module mux3( input a_i, b_i, c_i
input [1:0] sel_i,
output logic z_o );
always @( * )
case ( sel_i )
2’d0 : z_o = a_i;
2’d1 : z_o = b_i;
2’d2 : z_o = c_i;
default : z_o = 1’bx;
We CAN prevent creating a latch with a default statement

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others

What happens if the case statement is not complete?
module mux3( input a_i, b_i, c_i
input [1:0] sel_i,
output logic z_o );
always @( * )
always_comb
case ( sel_i )
2’d0 : z_o = a_i;
2’d1 : z_o = b_i;
2’d2 : z_o = c_i;
default : z_o = 1’bx;
SystemVerilog will protect you!

Be wary, many examples online are still plain ol’ Verilog, and will work fine … until they don’t 

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others

Parameterized mux4
module mux4 #( parameter width_p = 1 )
( input[width_p-1:0] a_i, b_i, c_i, d_i,
input [1:0] sel_i,
output[width_p-1:0] z_o );

wire [width_p-1:0] t0, t1;

assign t0 = (sel_i[1]? c_i : a_i);
assign t1 = (sel_i[1]? d_i : b_i);
assign z_o = (sel_i[0]? t0 : t1);
Instantiation
mux4#(.width_p(32)) alu_mux
( .a_i (op1),
.b_i (op2),
.c_i (op3),
.d_i (op4),
.sel_i(alu_mux_sel),
.z_o(alu_mux_out) );
default value

Parameterization is a good practice for reusable modules
Writing a muxn is challenging, but can be done with “idiomatic” verilog.

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others

SV Fundamentals
What is System Verilog?
Data types
Structural SV
Combinational Logic
Sequential Logic

module adder( input [3:0] A, B,
output cout,
output [3:0] S );
wire c0, c1, c2;
FA fa0( A[0], B[0], 1’b0, c0, S[0] );
FA fa1( A[1], B[1], c0, c1, S[1] );
FA fa2( A[2], B[2], c1, c2, S[2] );
FA fa3( A[3], B[3], c2, cout, S[3] );

CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others

logic q_r, q_n;

always_ff @( posedge clk )
q_r <= q_n; Sequential Logic: Creating a flip flop 1) This line simply creates two signals, one called q_r and the other called q_n. 2) always_ff keyword indicates our intent to create registers; you could use the always keyword instead, but this makes it clear what you want! 3) @( posedge clk ) indicates that we want these registers to be triggered on the positive edge of the clk clock signal. 4) Combined with 2) and 3), the <= creates a register whose input is wired to q_n and whose output is wired to q_r. Use _r to indicate a wire that comes directly out of a register, and _n (i.e., next) to indicate a wire that goes directly into one, and becomes the new output on the next cycle. note: always use <= with always_ff and = with always_comb CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others Sequential Logic: flip-flop idioms module FF (input clk, input d_i, input en_i, output logic q_r_o); always_ff @( posedge clk ) if ( en_i ) q_r_o <= d_i; module FF0 (input clk, input d_i, output logic q_r_o); always_ff @( posedge clk ) q_r_o <= d_i; CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others idiom: flip-flops with reset always_ff @( posedge clk) if (reset) else if ( enable ) synchronous reset CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others Register (i.e. a vector of parallel flip-flops) module register#(parameter width_p = 1) input clk, input [width_p-1:0] d_i, input en_i, output logic [width_p-1:0] q_r_o always_ff @( posedge clk ) q_r_o <= d_i; CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others Implementing Wider Registers module register2 (input clk, input [1:0] d_i, input en_i, output logic [1:0] q_r_o always_ff @(posedge clk) q_r_o <= d_i; module register2 ( input clk, input [1:0] d_i, input en_i, output logic [1:0] q_r_o FF ff0 (.clk(clk), .d_i(d_i[0]), .en_i(en_i), .q_r_o(q_r_o[0])); FF ff1 (.clk(clk), .d_i(d_i[1]), .en_i(en_i), .q_r_o(q_r_o[1])); Do they behave the same? CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others Syntactic Sugar: always_ff allows you to combine combinational and sequential logic; but this can be confusing. module accum #(parameter width_p=1) ( input clk, input data_i, input en_i, output logic [width_p-1:0] sum_o; logic [width_p-1:0] sum_r; assign sum_o = sum_r; always_ff @(posedge clk) sum_r <= sum_r + data_i; module accum #(parameter width_p=1) ( input clk, input data_i, input en_i, output logic [width_p-1:0] sum_o; logic [width_p-1:0] sum_r, sum_next; assign sum_o = sum_r; always_comb sum_next = sum_r; sum_next = sum_r + data_i; always_ff @(posedge clk) sum_r <= sum_next; more clear CC BY-NC-ND Pat Pannuto – Content derived from materials from , , , and others Syntactic Sugar: You can always convert an always_ff that combines combinational and sequential logic into two separate always_ff and always_comb blocks. module accum #(parameter width_p=1) ( input clk, input data_i, input en_i, output logic [width_p-1:0] sum_o; logic [width_p-1:0] sum_r; assign sum_o = sum_r; always_ff @(posedge clk) sum_r <= sum_r + data_i; module accum #(parameter width_p=1) ( input clk, input data_i, input en_i, output logic [width_p-1:0] sum_o; reg [width_p-1:0] sum_r, sum_next; assign sum_o = sum_r; always_comb sum_next = sum_r; sum_next = sum_r + 程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com