• Tidak ada hasil yang ditemukan

PDF Chapter 6: Hierarchical Structural Modeling - Seoul National University

N/A
N/A
Protected

Academic year: 2024

Membagikan "PDF Chapter 6: Hierarchical Structural Modeling - Seoul National University"

Copied!
33
0
0

Teks penuh

(1)

Chapter 6: Hierarchical Structural

Modeling

(2)

Objectives

After completing this chapter, you will be able to:

 Describe the features of hierarchical structural modeling in Verilog HDL

 Describe the features of Verilog modules

 Describe how to define and override the parameters within a module

 Describe the port connection rules

 Describe how to write a parameterized module

 Describe how to use generate block statements

(3)

Modules (p. 163 in LRM)

 Two major parts:

 Interface: communicates with the outside of the module

 Body: defines the functionality of the module.

(4)

Module Definitions

// port list style

module module_name [#(parameter_declarations)][port_list];

parameter_declarations; // if parameter ports are used port_declarations;

other_declaration;

statements;

endmodule

// port list declaration style

module module_name [#(parameter_declarations)][port_declarations];

parameter_declarations; // if parameter ports are used other_declarations;

statements;

endmodule

(5)

Port Declarations

 Three types:

 input declares a group of signals as input ports.

 output declares a group of signals as output ports.

 inout declares a group of signals as bidirectional ports.

net net net

variable net

net net variable

module adder(x, y, c_in, sum, c_out);

(6)

Parameters (p. 170 in LRM)

 Parameters are not variables; they are constant.

 cannot modify their values at run time

 can be modified at compile time

 Two types of parameters

 module parameters

• parameter

• localparam

 specify parameters (chap7, p. 211 in LRM)

• specparam

(7)

Differences between specparams amd parameters

(8)

Constants Specified Options

 `define compiler directive

 is used to create a macro for text substitution.

 is usually placed at the head of a file or a separated file.

 can be used both inside and outside module definitions.

 An example: `define BUS_WIDTH 8

 parameter

 is the most common approach used to define parameters.

 can be modified by defparam or module instance parameter value assignment.

 An example: parameter BUS_WIDTH = 8;

 localparam

 is identical to parameter but cannot be be overridden.

 An example: localparam BUS_WIDTH = 8;

(9)

Parameter Ports

 Parameter port: parameters are placed between module name and port list/port list declarations.

module module_name

#(parameter SIZE = 7,

parameter WIDTH_BUSA = 24, WIDTH_BUSB = 8, parameter signed [3:0] mux_selector = 4’b0 )

(port list or port list declarations) ...

endmodule

(10)

Module Instantiations

 In Verilog HDL, module definitions cannot be nested.

 A module can incorporate a copy (called an instance) of another module into itself through instantiation.

 One or more instances can be created in a single module

instantiation statement

(11)

Module Instantiations

(12)

Port Connection Rules

 Port connection rules

 named association

.port_id1(port_expr1),..., .port_idn(port_exprn)

 positional association

port_expr1, ..., port_exprn

 each port_expr can be

• an identifier (a net or a variable)

• a bit-select of a vector

• a part-select of a vector

• a concatenation of the above

• an expression for input ports

(13)

A Parameterized Module

 Parameterized modules: the features or operations of a

module can be changed, called parameter override, when a module is instantiated by a higher-level module.

module adder_nbit(x, y, c_in, sum, c_out);

// I/O port declarations parameter N = 4; // set default value input [N-1:0] x, y;

input c_in;

output [N-1:0] sum;

output c_out;

(14)

Module Parameters Values

 How to change module parameters values

 defparam statement

 module instance parameter value assignment

(15)

Overriding Parameters

 Using the defparam statement

// define top level module

module two_counters(clock, clear, qout4b, qout8b);

input clock, clear;

output [3:0] qout4b;

output [7:0] qout8b;

module counter_nbits (clock, clear, qout);

parameter N = 4; // define counter size input clock, clear;

output reg [N-1:0] qout;

always @( posedge clear or negedge clock) begin // qout <= (qout + 1) % 2^n;

if (clear) qout <= {N{1'b0}};

else qout <= (qout + 1) ; end

endmodule

(16)

// define top level module

module two_counters(clock, clear, qout4b, qout8b);

input clock, clear;

output [3:0] qout4b;

output [7:0] qout8b;

// instantiate two counter modules

counter_nbits #(4) cnt_4b (clock, clear, qout4b);

counter_nbits #(8) cnt_8b (clock, clear, qout8b);

Overriding Parameters

 Using module instance parameter value assignment--- one parameter

module counter_nbits (clock, clear, qout);

parameter N = 4; // define counter size input clock, clear;

output reg [N-1:0] qout;

always @( posedge clear or negedge clock) begin // qout <= (qout + 1) % 2^n;

if (clear) qout <= {N{1'b0}};

else qout <= (qout + 1) ; end

endmodule

(17)

Overriding Parameters

 Using module instance parameter value assignment --- two parameters

// define top level module

module parameter_overriding_example(x, y, z, f);

input x, y, z;

output f;

hazard_static #(4, 8) example (x, y, z, f);

endmodule module hazard_static (x, y, z, f);

parameter delay1 = 2, delay2 = 5;

input x, y, z;

output f;

wire a, b, c; // internal net // logic circuit body

and #delay2 a1 (b, x, y);

hazard_static #(.delay2(4), .delay1(6)) example (x, y, z, f);

• parameter value assignment by name ---

minimize the chance of error!

(18)

Hierarchical Names

 An identifier can be defined within

 Modules

 Tasks

 Functions

 Named blocks (See Section 7.1.3)

 Hierarchical names

4bit_adder // top level --- 4bit_adder 4bit_adder.fa_1 // fa_1 within 4bit_adder

4bit_adder.fa_1.ha_1 // ha_1 within fa_1

4bit_adder.fa_1.ha_1.xor1 // xor1 within ha_1

4bit_adder.fa_1.ha_1.xor1.S // net s within xor1

(19)

Overriding Parameters

module vdff (out, in, clk);

parameter size=1, delay=1;

input [0:size-1] in;

input clk;

output [0:size-1] o;

reg [0:size-1] out;

always @(posedge clk)

#delay out = inn;

endmodule module top;

reg clk;

reg [0:4] in1;

reg [0:9] in2;

wire [0:4] o1;

wire [0:9] o2;

vdff m1(o1,in1, clk);

vdff m2(o2, in2, clk);

endmodule

module annotate;

defparam

top.m1.size=5;

(20)

generate Block Structures

 The keywords used are generate and endgenerate.

 It is evaluated during the elaboration

 Generate statements allows control over

 the declaration of variables, functions, tasks, and module instantiation.

// an example illustrating the usage of generate statement.

// an example of converting Gray code into binary code.

module gray2bin1 (gray, bin);

parameter SIZE = 8; // this module is parameterized input [SIZE-1:0] gray;

output [SIZE-1:0] bin;

genvar i; // generate statement variable.

generate for (i = 0; i < SIZE; i = i + 1) begin: bit assign bin[i] = ^gray[SIZE-1:i];

end

endgenerate

(21)

generate Block Structures

 The data types allowed in generate block structure:

 net, reg

 integer, real, time, realtime,

 event

 What not permitted in a generate block

 parameters, local parameters

 input, output, inout declarations

 specify blocks

 Ways to create generate blocks:

(22)

The generate Loop Construct

 Generate loop can be nested. Within a generate loop

 The loop index is declared by the keyword genvar.

 genvar is used as an integer during elaboration to create instances of the generate block, but it does not exist during simulation time.

 Two generate loops using the same genvar as an index cannot be nested.

 A generate loop allows to instantiate

 modules, gate primitives, UDPs

 continuous assignments

 initial and always blocks

(23)

The generate Loop Construct

// an example illustrating the usage of generate statement.

// an example of converting Gray code into binary code.

module gray2bin2 (gray, bin);

parameter SIZE = 8; // this module is parameterized.

input [SIZE-1:0] gray;

output [SIZE-1:0] bin;

reg [SIZE-1:0] bin;

genvar i; // generate variable //generate loop

generate for (i = 0; i < SIZE; i = i + 1) begin:bit

always @(*) // using always @(*) to avoid synthesized warning.

(24)

The generate Conditional Construct

 Based on an if-else-if conditional expression, a generate conditional allows to instantiate

 modules, gate primitives, UDPs

 continuous assignments

 initial and always blocks

(25)

The generate Conditional Construct --- An n-bit Adder

 Three examples are used to illustrate the usage of generate statement:

 Modules

 Continuous assignment

 always statement

// define a full adder at dataflow level.

module full_adder(x, y, c_in, sum, c_out);

// I/O port declarations

input x, y, c_in;

(26)

The generate Conditional Construct --- An n-bit Adder

module adder_nbit(x, y, c_in, sum, c_out);

parameter N = 4; // define n as a parameter input [N-1:0] x, y;

input c_in;

output [N-1:0] sum;

output c_out;

// specify the function of an n-bit adder using generate.

genvar i;

wire [N-2:0] c; // internal carries declared as nets.

generate for (i = 0; i < N; i = i + 1) begin: adder if (i == 0) // specify LSB

full_adder fa (x[i], y[i], c_in, sum[i], c[i]);

else if (i == N-1) // specify MSB

full_adder fa (x[i], y[i], c[i-1], sum[i], c_out);

else // specify other bits

full_adder fa (x[i], y[i], c[i-1], sum[i], c[i]);

end

endgenerate

Instantiate modules inside generate block.

(27)

The generate Conditional Construct --- An n-bit Adder

module adder_nbit(x, y, c_in, sum, c_out);

parameter N = 4; // define N as a parameter input [N-1:0] x, y;

input c_in;

output [N-1:0] sum;

output c_out;

// specify the function of an n-bit adder using generate genvar i;

wire [N-2:0] c; // internal carries declared as nets.

generate for (i = 0; i < N; i = i + 1) begin: adder if (i == 0) // specify LSB

assign {c[i], sum[i]} = x[i] + y[i] + c_in;

else if (i == N-1) // specify MSB

Using continuous assignments inside generate block.

(28)

The generate Conditional Construct --- An n-bit Adder

module adder_nbit(x, y, c_in, sum, c_out);

parameter N = 4; // define N as a parameter input [N-1:0] x, y;

input c_in;

output reg [N-1:0] sum;

output reg c_out;

// specify the function of an n-bit adder using generate genvar i;

reg [N-2:0] c; // internal carries declared as nets.

generate for (i = 0; i < N; i = i + 1) begin: adder if (i == 0) // specify LSB

always @(*) {c[i], sum[i]} = x[i] + y[i] + c_in;

else if (i == N-1) // specify MSB

always @(*) {c_out, sum[i]} = x[i] + y[i] + c[i-1];

else // specify other bits

always @(*) {c[i], sum[i]} = x[i] + y[i] + c[i-1];

end endgenerate endmodule

An always block corresponds to a piece of logic.

Q: How can we specify a combinational logic or a sequential logic?

(29)

The generate Conditional Construct ---

2’s Complement Adder

module twos_adder_nbit(x, y, mode, sum, c_out);

// I/O port declarations

parameter N = 4; // define N as a parameter input [N-1:0] x, y;

input mode; // mode = 1: subtraction; =0: addition output [N-1:0] sum;

output c_out;

// specify the function of an n-bit two’s complement adder using generate genvar i;

wire [N-2:0] c; // internal carries declared as nets.

wire [N-1:0] t; // true/ones complement outputs generate for (i = 0; i < N; i = i + 1) begin:

(30)

The generate Conditional Construct ---

2’s Complement Adder generate for (i = 0; i < N; i = i + 1) begin: adder

if (i == 0) // specify LSB

full_adder fa (x[i], t[i], mode, sum[i], c[i]);

else if (i == N-1) // specify MSB

full_adder fa (x[i], t[i], c[i-1], sum[i], c_out);

else // specify other bits

full_adder fa (x[i], t[i], c[i-1], sum[i], c[i]);

end endgenerate endmodule

// define a full adder at dataflow level.

module full_adder(x, y, c_in, sum, c_out);

// I/O port declarations output sum, c_out;

input x, y, c_in;

// specify the function of a full adder assign {c_out, sum} = x + y + c_in;

(31)

The generate Conditional Construct ---

2’s Complement Adder

 The RTL schematic from Synplify Pro.

full_adder

adder\[0\].fa

full_adder

adder\[3\].fa

full_adder

adder\[1\].fa

full_adder

adder\[2\].fa t[0]

t[1] t[2] t[3]

[0] x

[0] y

c_in sum [0]

c_out [0]

[3] x

[3] y

[2] c_in

sum [3]

c_out

[1] x

[1] y

[0] c_in

sum [1]

c_out [1]

[2] x

[2] y

[1] c_in

sum [2]

c_out [2]

[0] [0]

[1] [1]

[2] [2]

[3] [3]

mode y[3:0] [3:0]

x[3:0] [3:0]

c_out sum[3:0]

[3:0]

(32)

The generate Conditional Construct ---

2’s Complement Adder

 After dissolving the second and the third bits.

[1]

[1]

[2]

full_adder [2]

adder\[0\].fa

full_adder

adder\[3\].fa

t[0]

t[1] t[2]

t[3]

adder\[1\].fa.sum_1[1:0]

+ adder\[2\].fa.sum_1[1:0]

+

[0] x

[0] y

c_in sum [0]

c_out [0]

[3] x

[3] y

[2] c_in

sum [3]

c_out

[0] [0]

[1] [1]

[2] [2]

[3] [3]

[1]

[1]

[0]

[2]

[2]

[1]

mode y[3:0] [3:0]

x[3:0] [3:0]

c_out sum[3:0]

[3:0]

(33)

The generate Case Construct

 Based on a case expression, a generate conditional allows to instantiate

 modules, gate primitives, UDPs,

 continuous assignments,

 initial and always blocks.

generate for (i = 0; i < N; i = i + 1) begin: adder case (i)

0: assign {c[i], sum[i]} = x[i] + y[i] + c_in;

N-1: assign {c_out, sum[i]} = x[i] + y[i] + c[i-1];

Referensi

Dokumen terkait