Loading in 2 Seconds...

Reconfigurable Computing (EN2911X, Fall07) Lecture 07: Verilog (3/3)

Loading in 2 Seconds...

- 68 Views
- Uploaded on

Download Presentation
## Reconfigurable Computing (EN2911X, Fall07) Lecture 07: Verilog (3/3)

**An Image/Link below is provided (as is) to download presentation**

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript

(EN2911X, Fall07)

Lecture 07: Verilog (3/3)

Prof. Sherief Reda

Division of Engineering, Brown University

http://ic.engin.brown.edu

Behavioral modeling

- Last lecture we started behavioral modeling
- Focus on synthesizable subset of Verilog
- Understood the difference between always and initial
- Understood the difference between blocking and nonblocking assignments
- Explained event-based control timing
- Explained conditional statements: if and else
- Explained multi-way branching: case
- Explained looping statements: while, for and repeat

As described, every module instance, signal, or variable is identified with an identifier.

Each identifier has a unique place in the design hierarchy.

Hierarchical name referencing allows us to denote every identifier in the design hierarchy with a unique name.

A hierarchical name is a list of identifiers separated by dots “.” for each level of hierarchy

Examples: stimulus.q, stimulus.m1.Q, stimulus.m1.n2

Hierarchical namingBlocks can be given names

Local variables can be declared from the names block

Variables in a named block can be accessed by using hierarchical name referencing

Named blocks can be disabled

Named blocks…

always

begin : block1

integer i;

i=1;

…

end

…

always

begin : block2

integer j;

j = block1.i^1;

end

The keyword disable provides a way to terminate the execution of a named block.

Disable can be used to get out of loops, handle error conditions, or control execution of pieces of code based on control signal

Disabling a block causes the execution control to be passed to the statement immediately succeeding the block

Disabling named blocksinitial

begin

i=0;

flag=8’b0010_0101;

begin: block1

while (i < 16)

begin

if (flag[i]) disable block1;

i = i+1;

end

end

Often it is required to implement the same functionality at many times in a behavioral design.

Verilog provides tasks and functions to break up large behavioral code into smaller pieces.

Tasks and functions are included in the design hierarchy. Like named blocks, tasks and functions can be addressed by means of hierarchical names.

Tasks have input, output and inout arguments

Functions have input arguments

Tasks and functions are included in the design hierarchy. Like named blocks, tasks or functions can be addressed by means of hierarchical names

Tasks and functionsTasks are declared with the keywords task and endtask.

Tasks can have input, inout, and output arguments to pass values (different than in modules).

Tasks or functions can have local variables but cannot have wires.

Tasks and functions can only contain behavioral statements.

Tasks and functions do not contain always or initial statements but are called from always blocks, initial blocks, or other tasks and functions.

Can operate directly on reg variables defined in the module

Tasksmodule …

…

always

begin

BOP (AB_AND, AB_OR, AB_XOR, A, B);

BOP (CD_AND, CD_OR, CD_XOR, C, D);

end

task BOP;

output [15:0] ab_and, ab_or, ab_xor;

input [15:0] a, b;

begin

ab_and = a & b;

ab_or = a | b;

ab_xor = a ^ b;

end

endtask

…

endmodule

Instantiated modules create duplicate copies in hardware.

In contrast tasks are static in nature. All declared items are statically allocated and they are shared across all uses of the task.

If a task is called form within a behavioral block, only one copy is needed

However, a task/function might be called concurrently form different behavioral blocks, which can lead to incorrect operation → avoid by using the automatic keyword to make a task re-entrant

Difference between module and task instantiationmodule …

…

always

BOP (AB_AND, AB_OR, AB_XOR, A, B);

always

BOP (CD_AND, CD_OR, CD_XOR, C, D);

task automatic BOP;

output [15:0] ab_and, ab_or, ab_xor;

input [15:0] a, b;

begin

ab_and = a & b;

ab_or = a | b;

ab_xor = a ^ b;

end

endtask

…

endmodule

Functions

- Functions are typically used for combinational modeling (use for conversions and commonly used calculations.
- Need at least one input argument but cannot have output or inout arguments.
- The function is invoked by specifying function name and input arguments, and at the end execution, the return value is placed where the function was invoked
- Functions cannot invoke other tasks; they can only invoke other functions. Recursive functions are not synthesizable

module …

…

reg [31:0] parity;

always @(addr)

begin

parity = calc_parity(addr);

end

// you can declare C sytle

function calc_parity;

input [31:0] address;

begin

calc_parity = ^address;

end

endfunction

…

endmodule

Last lecture we had a simple example of a 1 second blinking LED

Let’s generalize it to a clock display

Example: clock display on DE2minutes

HEX3 HEX2

seconds

HEX1 HEX0

Task to display digits

task digit2sev(input integer digit, output [6:0] disp);

begin

if (digit == 0) disp = 7'b1000000;

else if (digit == 1) disp = 7'b1111001;

else if (digit == 2) disp = 7'b0100100;

else if (digit == 3) disp = 7'b0110000;

else if (digit == 4) disp = 7'b0011001;

else if (digit == 5) disp = 7'b0010010;

else if (digit == 6) disp = 7'b0000011;

else if (digit == 7) disp = 7'b1111000;

else if (digit == 8) disp = 7'b0000000;

else if (digit == 9) disp = 7'b0011000;

end

endtask

One way

module clock(CLOCK_50, HEX0, HEX1, HEX2, HEX3);

output reg [6:0] HEX0, HEX1, HEX2, HEX3;

input CLOCK_50; integer count=0;

reg [3:0] d1=0, d2=0, d3=0, d4=0;

always @(posedge CLOCK_50)

begin

count=count+1;

if (count == 50_000_000)

begin

count=0; d1 = d1+1;

if(d1 == 10)

begin

d1 = 0; d2 = d2+1;

if(d2 == 6)

begin

d2 = 0; d3 = d3 + 1;

if(d3 == 10)

begin

d3 = 0; d4 = d4 + 1;

if(d4 == 6) d4 = 0;

end

end

end

digit2sev(d1, HEX0); digit2sev(d2, HEX1);

digit2sev(d3, HEX2); digit2sev(d4, HEX3);

end

end

task digit2sev;

…

endtask

endmodule

Second code

module clock(CLOCK_50, HEX0, HEX1, HEX2, HEX3);

input CLOCK_50;

output reg [6:0] HEX0, HEX1, HEX2, HEX3;

integer count=0;

reg [15:0] ticks=16'd0;

reg [5:0] seconds=6'd0, minutes=6'd0;

initial display_time(seconds, minutes);

always @(posedge CLOCK_50)

begin

count = count+1;

if (count == 50_000_000)

begin

count=0;

ticks = ticks + 1;

seconds = ticks % 60;

minutes = ticks / 60;

display_time (seconds, minutes);

end

end

task display_time(input [5:0] s, input [5:0] m);

begin

digit2sev(s%10, HEX0);

digit2sev(s/10, HEX1);

digit2sev(m%10, HEX2);

digit2sev(m/10, HEX3);

end

endtask

task digit2sev(input integer digit, output [6:0] disp);

begin

if (digit == 0) disp = 7'b1000000;

else if (digit == 1) disp = 7'b1111001;

else if (digit == 2) disp = 7'b0100100;

else if(digit == 3) disp = 7'b0110000;

else if(digit == 4) disp = 7'b0011001;

else if(digit == 5) disp = 7'b0010010;

else if(digit == 6) disp = 7'b0000011;

else if(digit == 7) disp = 7'b1111000;

else if(digit == 8) disp = 7'b0000000;

else if(digit == 9) disp = 7'b0011000;

end

endtask

endmodule

Circuit consumes 611 LEs (2% of the chip logic resources).

You have to be careful! Changing ticks, seconds and minutes to integer increases area to become 2500 LEs (8% of the utilization)

Resource utilization for 2nd code
Download Presentation

Connecting to Server..