Download presentation
1
The Verilog Hardware Description Language
2
GUIDELINES How to write HDL code:
3
GUIDELINES How NOT to write HDL code:
4
Think Hardware NOT Software
Poorly written HDL code will either be: Unsynthesizable Functionally incorrect Lead to poor performance/area/power results
5
Conventions Verilog IS case sensitive Syntax is based on C
CLOCK, clock and Clock are different Syntax is based on C but is interpreted differently
6
Verilog code basic structure
module module_name (ports); input input_signals; output output_signals; inout bidirectional signals; wire wire_signals; reg register_type_variables; primitive/component (ports); concurrent/sequential assignments endmodule
7
Port types PORT DIRECTION SIGNAL TYPE - IN -OUT -INOUT
scalar ( input x; ) Vector (input [WIDTH -1 : 0] x)
8
Module port declaration example (1/2)
module and_gate (o, i1, i2); output o; input i1; input i2; endmodule
9
Module port declaration example (2/2)
module adder (carry, sum, i1, i2); output carry; output [3:0] sum; input [3:0] i1, i2; endmodule
10
Example
11
Verilog Primitives Verilog primitives are models of common combinational logic gates Their functionality is built into the language and can be instantiated in designs directly The output port of a primitive must be first in the list of ports
12
Structural description example
module gates (o,i0,i1,i2,i3); output o; input i0,i1,i2,i3; wire s1, s2; and (s1, i0, i1); and (s2, i2, i3); and (o, s1, s2); endmodule
13
Verilog operators Arithmetic Bitwise Relational
+, - , *, Synthesizable /, % Non-synthesizable Bitwise & AND | OR ~ NOT ^ XOR ~^ XNOR Relational =, <, >, <=, >=
14
User-Defined Primitives Truth Table Models
primitive my_UDP (y, x1, x2, x3); output y; //the output of a primitive cannot be a vector!! input x1, x2, x3; table //x1 x2 x3 : y 0 0 0 : 0; 0 0 1 : 1; 0 1 0 : 0; 0 1 1 : 0; 1 0 0 : 1; 1 0 1 : 0; 1 1 0 : 1; 1 1 1 : 0; endtable endprimitive
15
Truth tables with don’t cares
//? Represents a don’t care condition // on the input //i1 i2 i3 : y : 0 : 1 : 0 : 0 1 ? ? : 1 endtable
16
variable assignment variable_name = value; //blocking assignment
variable_name <= value; //non-blocking assignment Examples output a; output [6:0] b; reg [3:0] c; wire [2:0] d; Correct Incorrect a = 1; a <= 3; b <= 7’b ; b = 9’b ; b[1] = 0; c <= 0; d <= 0; d <= {b , c}; b <= {c, d}; b[5:2] <= c;
17
Propagation delay Used to assign variables or primitives with delay, modeling circuit behaviour # 5 and (s, i0, i1); ns and gate delay #5 assign s = i0 & i1; ns and gate delay #1 assign a = b; --1 ns wire delay Not synthesizable, is ignored by synthesis tools Useful in testbenches for creating input signal waveforms always #20 clk = ~clk ns clock period #0 rst_n = 0; #10 rst_n = 1;
18
Concurrent statements –delta time
b = ~ a; (a = 1, b = 1, c =0) c = a ^ b; Time a b c δ 2δ
19
Continuous assignment
Multiple driver error assign c = a & b; …. assign c = d | e;
20
Combinational circuit description
module gates (d, a, c); output d; input a, c; //wire b; assign d = c ^ (~a); // assign b = ~a; // assign d = c ^ b; endmodule
21
Arithmetic unit description (full-adder)
module add1 (cout, sum, a, b, cin); input a, b; input cin; output sum; output cout; assign {cout,sum} = a + b + cin; endmodule
22
Example Describe a 5-bit multiplier in Verilog.
23
Conditional assignment - describing MUXs
assign = select_signal ? assignment1 : assignment1 module mux (o, s, i0, i1); output o; input i0, i1; input s; assign o = s ? i1 : i0; //if s =1 then o = i1, else o =i0 endmodule
24
Cyclic behavior Statements in cyclic behavior execute sequentially
Can be used to describe either combinational circuits (optional) or sequential circuits (only way) Signals assigned in always blocks must be of type reg always & (sensitivity list) begin sequential statements end
25
Combinational Circuit Description using Cyclic Behavior
(a or b or c) begin d = (a & b) | c; end ALL input signals must be in sensitivity list or latches will be produced!
26
If statement (sequential)– describing MUXs
if (condition1) begin signal1 <= value1; signal2 <= value2; end else if (condition2) begin signal1 <= value3; signal2 <= value4; … else begin signal1 <= valuen-1; signal2 <= valuen; module mux (o, s, i0, i1); output o; reg o; input i0, i1; input s; (i0 or i1 or s) begin if (s == 0) o = i0; else o = i1; end endmodule
27
CASE statement (sequential)– describing MUXs
module mux (o, s, i0, i1); output o; reg o; input i0, i1; input s; (i0 or i1 or s) begin case (s) 0: o = i0; 1: o = i1; default: o= 1’bx; endcase end endmodule case (signal) value1: signal1 <= value2; signal2 <= value3; value2 : signal1 <= value4; signal2 <= value5; . . . default: signal1 <= valuen-1; signal2 <= valuen; endcase
28
Example Describe a 3-bit 4-to-1 MUX
29
CLOCKED PROCESS (Latch with asynchronous reset)
(clk or rst_n) begin if (rst_n == 0) q <= 0; else if (clk == 1) q <= d; end
30
CLOCKED PROCESS (Latch with synchronous reset)
(clk or rst_n) begin if (clk == 1) q <= d; else if (rst_n == 0) q <= 0; end
31
CLOCKED PROCESS (Flip-flop with asynchronous reset)
clk or negedge rst_n) begin if (rst_n == 0) q <= 0; else q <= d; end
32
CLOCKED PROCESS (Flip-flop with synchronous reset)
clk) begin if (rst_n == 0) q <= 0; else q <= d; end
33
for loop statement – shift register
module shift_reg (o, clk, rst_n, i); output o; input i; input clk, rst_n; reg [3:0] d; integer k; (posedge clk or negedge rst_n) begin if (rst_n ==0) d <= 0; else d[0] <= i; for (k=0; k <4; k=k+1) d[k+1] <= d[k]; end assign o = d[3]; endmodule
34
CLOCKED VS COMBINATIONAL PROCESS (1/2)
(posedge clk or negedge rst_n) begin if (rst_n == 0) q <= 0; else case (c) 0: q = a; 1: q = b; default: q= 1’bx; endcase end (a or b or c) begin case (c) 0: q = a; 1: q = b; default: q= 1’bx; endcase end
35
CLOCKED VS COMBINATIONAL PROCESS (2/2)
(a or b or c) begin d = (a & b) | c; end (posedge clk) begin if (rst_n == 0) d <= 0; else d <= (a & b) | c; end
36
EXAMPLE DESCIBE A BINARY UP/DOWN COUNTER WITH ENABLE THAT COUNTS UPTO 12 AND THEN STARTS AGAIN FROM ZERO
37
TESTBENCH `timescale 1ns / 100ps module testbench_name ();
reg ….; //declaration of register variables for DUT inputs wire …; //declaration of wires for DUT outputs DUT_name(DUT ports); initial $monitor(); //signals to be monitored (optional) initial begin #100 $finish; //end simulation end initial begin clk = 1’b0; //initialize clk #10 a = 0; #10 a = 1; … always # 50 clk = ~clk; //50 ns clk period (if there is a clock) endmodule
38
TESTBENCH EXAMPLE `timescale 1ns / 100ps module mux_tb ();
reg i0, i1, s; wire o; mux M1 (o, s, i0, i1); initial begin #100 $finish; //end simulation end initial begin //stimulus pattern #10 i0 = 0; i1=0; s=0; #10 i0=1; #10 i0 = 0; i1=1; #10 i0=0; i1= 0; s=1; end endmodule
39
FINITE STATE MACHINES
40
FINITE STATE MACHINE IMPLEMENTATION
41
Mealy machines (1/5) module fsm (y, clk, rst_n, x); output y;
input clk, rst_n, x; reg [1:0] state_pr, state_nx; reg y; parameter a = 0, b = 1, c = 2, d = 3, dont_care_state = 2’bx, dont_care_out = 1’bx;
42
Mealy machines (2/5) (posedge clk or negedge rst_n) //state memory begin if (rst_n == 0) state_pr <= a; //default state else state_pr <= state_nx; end
43
Mealy machines (3/5) always @ (x or state_pr) //combinational part
begin CASE (state_pr) a: if (x == 1) begin state_nx = b; y=0; end else if (x == 0) begin state_nx <= a; --optional
44
Mealy machines (4/5) state_nx = c; y=0; --Mealy machine end
b: if (x == 1) begin state_nx = c; y=0; --Mealy machine end else if (x==0) begin state_nx <= a; y=0; --Mealy machine c: if (x == 1) begin state_nx = c; --optional state_nx <= d;
45
Mealy machines (5/5) d: if (x == 1) begin state_nx = b;
y=1; --Mealy machine end else if (x==0) begin state_nx <= a; y=0; --Mealy machine default: begin state_nx <= dont_care_state; y <= dont_care_out; endcase endmodule
46
Moore machines always @ (x or state_pr) --combinational part begin
CASE (state_pr) s0: y = <value>; Moore machine if (a == 1) state_nx = s1; else state_nx = s0; --optional
47
MOORE MACHINES S1: y = <value>; --Moore machine if (x == 1)
state_nx = S0; else state_nx = S1; --optional endcase end
48
EXAMPLE: OUT-OF-SEQUENCE COUNTER
DESCRIBE A COUNTER WITH THE FOLLOWING SEQUENCE: “000” => “010” => “011” => “001” => “111” => “000”
49
ROM description (1/2) module rominfr (data, en, addr);
output [3:0] data; input en; input [4:0] addr; reg [3:0] ROM [31:0]; assign data = ROM[addr];
50
ROM description (2/2) initial begin
ROM[0] = 4’b0001; ROM[1] = 4’b0010; ROM[2] = 4’b0011; ROM[3] = 4’b0100; ROM[4] = 4’b0101; ROM[5] = 4’b0110; ROM[6] = 4’b0111; ROM[7] = 4’b1000; ROM[8] = 4’b1001; ROM[9] = 4’b1010; ROM[10] = 4’b1011; ROM[11] = 4’b1100; ROM[12] = 4’b1101; ROM[13] = 4’b1110; ROM[14] = 4’b1111; ROM[15] = 4’b0001; ROM[16] = 4’b0010; ROM[17] = 4’b0011; ROM[18] = 4’b0100; ROM[19] = 4’b0101; ROM[20] = 4’b0110; ROM[21] = 4’b0111; ROM[22] = 4’b1000; ROM[23] = 4’b1001; ROM[24] = 4’b1010; ROM[25] = 4’b1011; ROM[26] = 4’b1100; ROM[27] = 4’b1101; ROM[28] = 4’b1110; ROM[29] = 4’b1111; ROM[30] = 4’b0000; ROM[31] = 4’b0001; end endmodule
51
DUAL –PORT RAM (1/2) module v_rams_12 (clk1, clk2, we, add1, add2, di, do1, do2); input clk1; input clk2; input we; input [5:0] add1; input [5:0] add2; input [15:0] di; output [15:0] do1; output [15:0] do2; reg [15:0] ram [63:0]; reg [5:0] read_add1; reg [5:0] read_add2;
52
DUAL –PORT RAM (2/2) always @(posedge clk1) begin if (we)
ram[add1] <= di; read_add1 <= add1; end assign do1 = ram[read_add1]; clk2) begin read_add2 <= add2; assign do2 = ram[read_add2]; endmodule
53
Include files `include "timing.vh"
module counter1(count, reset, clk) ; output [7:0] count; input reset, clk; reg [7:0] count; clk or posedge reset) if(reset) count <= #(`REG_DELAY) 8'b0; else count <= #(`REG_DELAY) count + 8 'b1; . . . //contents of ”timing.vh” file `timescale Ins/Ins `define REG_DELAY 1
54
Parametric models `include “rominfr_pkg.vh”
module rominfr (data, en, addr); output [`wordlength-1:0] data; input en; input [`addr_size-1:0] addr; reg [`wordlength-1:0] ROM [`ROM_size-1:0]; . . . //contents of “rominfr_pkg.vh” `define wordlength 8 `define addr_size 5 `define ROM_size 32
55
Example Create an ALU with parametric wordlength, and the following function table S2 S1 S0 FUNCTION A + B A – B A + 1 B + 1 A AND B A OR B A XOR B NOT A
56
Common Verilog Pitfalls
57
Name inconsistency Compile: error Severity: Trivial
module wrong_name (o, i0, i1, i2); output o; input i1, i2, i3; assign o = i0 & i1 ^ i2; endmodule
58
Multiple unconditional concurrent assignments
Simulation: ‘X’ value Synthesis: ERROR: signal is multiply driven Severity: Serious module … assign x = a & b; ... assign x = b ^ c; (b or c) begin x <= b | c; end
59
Incomplete sensitivity list
Simulation: Unexpected behavior Synthesis: Warning: Incomplete sensitivity list Severity: Serious Solution: complete sensitivity list (a or b) begin d <= (a & b) | c; //c is missing from sensitivity list!!! end
60
Not assigning all outputs in combinational always block
Simulation: Synthesis: Warning: Signal not always assigned, storage may be needed Severity: Serious Solution: assign all signals (a or b or c) begin if (c == 0) then d <= (a & b) | c; //d assigned only first time, else if (c == 1) e <= a; //e assigned only second time!!! end
61
Unassigned signals Simulation: Undefined value (‘U’)
Synthesis: Warning: Signal is never used/never assigned a value Severity: Moderate module … output y; input input1, input2; wire s; assign y = input1 & input2; //s never assigned endmodule
62
Output not assigned or not connected
Simulation: Undefined Synthesis: Error: All logic removed from the design Severity: Serious module my_module (o, input1, input2); output o; input input1, input2; wire s; assign s = input1 & input2; //output never assigned endmodule
63
Using sequential instead of concurrent process
Simulation: Unexpectedly delayed signals Synthesis: More FFs than expected
64
Confusing reg with wire
module my_module (o, input1, input2); output o; input input1, input2; assign o = input1 & input2; //output is wire by default endmodule reg o; (input1 or input2) //using always block o = input1 & input2; //output must be reg
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.