Verilog Design Examples: Writing Synthesizable Code and GCD Implementation, Lecture notes of Design history

Verilog design examples for writing synthesizable code and implementing a Greatest Common Divisor (GCD) function. It covers guidelines for synthesizable Verilog, parameterized models, and explicit state representation. The document also includes examples of datapath design and control logic for a GCD implementation.

Typology: Lecture notes

2021/2022

Uploaded on 08/01/2022

fabh_99
fabh_99 🇧🇭

4.4

(53)

543 documents

1 / 41

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Courtesy of Arvind L03-1
Verilog 2 - Design Examples
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22
pf23
pf24
pf25
pf26
pf27
pf28
pf29

Partial preview of the text

Download Verilog Design Examples: Writing Synthesizable Code and GCD Implementation and more Lecture notes Design history in PDF only on Docsity!

Verilog 2 - Design Examples

Verilog can be used at

several levels

automatic tools to

synthesize a low-level

gate-level model

High-Level Behavioral

Register Transfer Level

Gate Level

A common approach is to

use C/C++ for initial

behavioral modeling, and

for building test rigs

Writing synthesizable Verilog:

Sequential logic

! Use always @(posedge clk) and non- blocking assignments (<=) always @( posedge clk ) C_out <= C_in; ! Use only positive-edge triggered flip-flops for state ! Do not assign the same variable from more than one always block – ill defined semantics ! Do not mix blocking and non-blocking assignments ! Only leaf modules should have functionality; use higher-level modules only for wiring together sub-modules

wire A_in, B_in, C_in; reg A_out, B_out, C_out; always @( posedge clk ) begin A_out <= A_in; B_out <= A_out + 1; C_out <= B_out + 1; end

An example

A

B C

The order of non-blocking

assignments does not

matter!

Why? Because they

generate registers!

wire A_in, B_in, C_in; reg A_out, B_out, C_out; always @( posedge clk ) begin A_out <= A_in; B_out <= B_in; C_out <= C_in; assign B_in = A_out + 1; assign C_in = B_out + 1; end

An example:

Some wrong solutions

A

B C

Syntactically illegal

Another style – multiple

always blocks

wire A_in, B_in, C_in; reg A_out, B_out, C_out; always @( posedge clk ) A_out <= A_in; assign B_in = A_out + 1; always @( posedge clk ) B_out <= B_in; assign C_in = B_out + 1; always @( posedge clk ) C_out <= C_in;

A

B C

Does it have the

same functionality?

It generates the same

underlying circuit.

Yes. But why?

L03-

Verilog execution semantics

  • Confusing
  • Best solution is to write synthesizable verilog that corresponds exactly to logic you have already designed on paper, as described by the “verilog breakdown” slide. Courtesy of Arvind

!"#$%&'()+,-$+.+/0)1/&+$%2)/,"34+5() "$6"#()789:) ));/2+3) )))));))))<).8":) )))))5))))<)0)=)>?) )/30) @AB@AC@) DCEFG) "((+23)0)<);=B?) "((+23)/)<)5=B?) "$6"#()) ))78-%(/02/)5$H:) ));/2+3) ))))))")I<)

))))))J)I<)

))/30) "$6"#()) ))78-%(/02/)5$H:) ));/2+3) ))))))K)I<)

))))))&)I<)

))/30) "$6"#()) ))78-%(/02/)5$H:) ));/2+3) ))))))))I<).%%?)

))))))))I<);"&?)

))/30) "$6"#()) ))78-%(/02/)5$H:) ));/2+3) )))))).%%)<)K?)

))/30)

L$%5H)M02/)

N3%&0/&/0)

N3%&0/&/0)

"N4%F%&0/&/0)

If you treat verilog as a language for coding up hardware you have already designed on paper/whiteboard, you will not need to rely on this. (combinational) (sequential left hand side) (sequential right hand side)

Verilog Design Examples

! Greatest Common Divisor

! Unpipelined SMIPSv1 processor

L03-

GCD in C

int GCD( int inA, int inB) { int done = 0; int A = inA; int B = inB; while ( !done ) { if ( A < B ) { swap = A; A = B; B = swap; } else if ( B != 0 ) A = A - B; else done = 1; } return A; }

Such a GCD description can be

easily written in Behavioral

Verilog

It can be simulated but it will

have nothing to do with

hardware, i.e. it won’t

synthesize.

We don’t spend much time on

Behavioral Verilog because it

is not a particularly good

language and isn’t useful for

hardware synthesis.

Step 1: Design an

appropriate port interface

idle input_available operand_A operand_B result_data result_taken result_rdy clk reset

Step 2: Design a datapath which has the functional units B A = inA; B = inB; while ( !done ) begin if ( A < B ) swap = A; A = B; B = swap; else if (B != 0) A = A - B; else done = 1; End Y = A; zero? lt A sub

Datapath module interface

module GCDdatapath#( parameter W = 16 ) ( input clk, // Data signals input [W-1:0] operand_A, input [W-1:0] operand_B, output [W-1:0] result_data, // Control signals (ctrl->dpath) input A_en, input B_en, input [1:0] A_sel, input B_sel, // Control signals (dpath->ctrl) output B_zero, output A_lt_B ); B A sel A en B sel B en B = 0 A < B zero? lt A sub

Connect the modules

wire [W-1:0] B; wire [W-1:0] sub_out; wire [W-1:0] A_out; vcMux3#(W) A_mux ( .in0 (operand_A), .in1 (B), .in2 (sub_out), .sel (A_sel), .out (A_out) ); wire [W-1:0] A; vcEDFF_pf#(W) A_pf ( .clk (clk), .en_p (A_en), .d_p (A_out), .q_np (A) ); B A sel A en B sel B en B = 0 A < B zero? lt A sub