Parameterization and Code Generation in Verilog, Slides of Computer Science

The concept of parameterization and code generation in verilog, including the use of parameters, generated instantiation, functions and tasks, and compiler directives. It covers topics such as making code more readable, improving reusability, and generating different-sized structures using special generate variables and generate-loops.

Typology: Slides

2012/2013

Uploaded on 03/27/2013

agarkar
agarkar šŸ‡®šŸ‡³

4.3

(26)

372 documents

1 / 45

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
ECE 551
Digital System Design & Synthesis
Lecture 07
Parameters
Code Generation
Functions & Tasks
Docsity.com
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
pf2a
pf2b
pf2c
pf2d

Partial preview of the text

Download Parameterization and Code Generation in Verilog and more Slides Computer Science in PDF only on Docsity!

ECE 551

Digital System Design & Synthesis

Lecture 07

Parameters Code Generation Functions & Tasks

Elaboration of Verilog Code

Overview

• Parameters

• Generated Instantiation

• Functions and Tasks

• ā€œCompilerā€ Directives

Parameters

• Compile-time constant parameters in Verilog

  • In Verilog: parameter N=8’d100;
  • Values are substituted during Elaboration; parameters cannot change value after synthesis

• Can be used for three main reasons

  • Make code more readable
  • Make it easier to update code
  • Improve (re)usability of modules

Reusability/Extensibility of Modules

7

module xor_array(y_out, a, b); parameter SIZE = 8, DELAY = 15; // parameter defaults output [SIZE-1:0] y_out; input [SIZE-1:0] a,b; wire #DELAY y_out = a ^ b; endmodule

xor_array G1 (y1, a1, b1); // use defaults xor_array #(4, 5) G2(y2, a2, b2); // override default parameters // SIZE = 4, DELAY = 5

  • Module instantiations cannot specify delays without

parameter s

  • Where would delays go? What type would they be?

Overriding Parameters

  • Parameters can be overridden
    • Generally done to ā€œresizeā€ module or change its delay
  • Implicitly: override in order of appearance
    • xor_array #(4, 5) G2(y2, a2, b2);
  • Explicitly: name association (preferred)
    • xor_array #(.SIZE(4), .DELAY(5)) G3(y2, a2, b2);
  • Explicitly: defparam
    • defparam G4.SIZE = 4, G4.DELAY = 15;
    • xor_array G4(y2, a2, b2);
  • localparam parameters in a module can’t be overridden
    • localparam SIZE = 8, DELAY = 15;

Parameterized Ripple Carry Adder

10

module RCA(sum, c_out, a, b, c_in); parameter BITS=8; input [BITS-1:0] a, b; input c_in; output [BITS-1:0] sum; output c_out; wire [BITS-1:1] c;

Add_full M[BITS-1:0](sum, {c_out, c[BITS-1:1]}, a, b, {c[BITS-1:1], c_in}); endmodule

ļ‚§ Instantiate a 16-bit ripple-carry adder:

RCA #(.BITS(16)) add_16(sum, carryout, a, b,

carryin);

Parameterized Shift Register [2]

12

module shift_bhv (outbit, out, in, clk, rst);

parameter WIDTH = 8; output [WIDTH-1:0] out; output outbit; input in; always @( posedge clk) begin if (rst) {outbit,out} <= 0; else {outbit,out} <= {out[WIDTH-1:0],in}; end

endmodule

ļ‚§ Instantiate a 16-bit shift register:

shift_bhv #(16) shift_16(shiftbit, shiftout, shiftin, clk, rst);

Generated Instantiation

• Generate statements: control over the

instantiation/creation of

– Modules, gate primitives, continuous assignments,

initial blocks, always blocks, nets and regs

• Generate instantiations are resolved during

Elaboration

– Can alter or replace a piece of code based on

compile-time information

– Before the design is simulated or synthesized

Special Generate Variables

• Index variables used in generate statements;

declared using genvar (e.g., genvar i )

• Useful when developing parameterized

modules

• Can override the parameters to create

different-sized structures

• Easier than creating different structures for all

different possible bitwidths

Generate Loops in LHC Firmware

17

input [CLUSTER_ET_SIZE-1:0] cluster_grid[GRID_X-1:0][GRID_Y-1:0]; wire eg_grid_mask[GRID_X-1:0][GRID_Y-1:0]; wire eg_grid_mask[GRID_X-1:0][GRID_Y-1:0]; …… genvar i, j;

generate begin : mask_gen

for (i = 0; i < GRID_X; i=i+1) begin : xcoord for (j = 0; j < GRID_Y; j=j+1) begin : ycoord

logic [CLUSTER_ET_SIZE-1:0] central_et = cluster_grid[i][j]; assign eg_grid_mask [i][j] = (central_et >= EG_THRESHOLD); assign tau_grid_mask[i][j] = (central_et >= TAU_THRESHOLD);

end end end endgenerate //This must be SystemVerilog. Why?

Accessing Data from other Loops

18

generate for (i = 0; i < GRID_X; i = i + 1) begin : aliasing_x for (j = 0; j < GRID_Y; j = j + 1) begin : aliasing_y

if ((i >= ISO_X1) && (i <= ISO_X2) && (j >= ISO_Y1) && (j <= ISO_Y2)) begin

assign et_array[i-ISO_X1][j-ISO_Y1] = mask_gen.xcoord[i].ycoord[j].central_et ;

assign eg_correction [i-ISO_X1][j-ISO_Y1] = eg_grid_mask[i][j];

assign tau_correction[i-ISO_X1][j-ISO_Y1] = tau_grid_mask[i][j]; end end end endgenerate

Generate-Case

  • A generate-case allows conditional (pre-synthesis)

instantiation using case constructs

  • See Standard 12.1.3 for more details

module adder ( output co, sum, input a, b, ci);

parameter WIDTH = 8; generate case (WIDTH) 1: adder_1bit x1(co, sum, a, b, ci); // 1-bit adder implementation 2: adder_2bit x1(co, sum, a, b, ci); // 2-bit adder implementation default : adder_cla #(WIDTH) x1(co, sum, a, b, ci); endcase

endgenerate

endmodule 20

Can have a ā€œdefaultā€ in a generate-case

Generate a Pipeline [Part 1]

21

module pipeline(out, in, clk, rst); parameter BITS = 8; parameter STAGES = 4; input [BITS-1:0] in; output [BITS-1:0] out; wire [BITS-1:0] stagein [0:STAGES-1]; // value from previous stage reg [BITS-1:0] stage [0:STAGES-1]; // pipeline registers

assign stagein[0] = in; generate genvar s; for (s = 1; s < STAGES; s = s + 1) begin : stageinput assign stagein[s] = stage[s-1]; end endgenerate

// continued on next slide