Design Synthesis
Design Synthesis
(System)Verilog
LE
LE
LE
LE
LE
LE
LE
LE
M
E
M
LE
M
E
M
LE
LE
LE
Modules
Module design entity
ports and description
module and_or_1_bit (input logic x, y,
output logic f, g);
x
y
assign f = x & y;
assign g = x | y;
endmodule
bit0(.x(x[0]),
bit1(.x(x[1]),
bit2(.x(x[2]),
bit3(.x(x[3]),
.y(y[0]),
.y(y[1]),
.y(y[2]),
.y(y[3]),
.f(f[0]),
.f(f[1]),
.f(f[2]),
.f(f[3]),
.g(g[0]));
.g(g[1]));
.g(g[2]));
.g(g[3]));
and_or_1_bit
and_or_1_bit
and_or_1_bit
and_or_1_bit
bit4(.x(x[4]),
bit5(.x(x[5]),
bit6(.x(x[6]),
bit7(.x(x[7]),
.y(y[4]),
.y(y[5]),
.y(y[6]),
.y(y[7]),
.f(f[4]),
.f(f[5]),
.f(f[6]),
.f(f[7]),
.g(g[4]));
.g(g[5]));
.g(g[6]));
.g(g[7]));
endmodule
assign f = x & y;
assign g = x | y;
endmodule
Operators
The most relevant Verilog operators
(for this stage of our course)
Operator Usage
Description
Logical Operators (1-bit result true/false)
!
&&
||
!A
A && B
A || B
Is A NOT true?
Are both A AND B true?
Are either A OR B true?
~A
A&B
A|B
A^B
A ~^ B
A^~ B
&A
~&A
|A
~|A
^A
~^A
A+B
A-B
-A
Add A to B
Subtract B from A
Take 2s complement of A
A==B
A!=B
A<B
A>B
A<=B
A>=B
Is A equal to B?
Is A not equal to B?
Is A less than B?
Is A greater than B?
Is A less than or equal to B?
Is A greater than or equal to B?
Multiplexers
Using continuous signal assignment
module mux_2_to_1 (input logic sel,
input logic[7:0] x, y,
output logic[7:0] f);
assign f = sel ? x : y;
endmodule
or
module mux_2_to_1 (input logic sel,
input logic[7:0] x, y,
output logic[7:0] f);
always_comb
begin
f = y;
if (sel) f = x;
end
endmodule
0
1
f
sel1
0
1
problem
or
module multiple_drivers_fixed (input logic sel1, sel2,
input logic[7:0] x, y,
output logic[7:0] f);
assign f = sel1 ? x : (sel2 ? y : x);
endmodule
Priority Encoders
module priority_encoder (input logic c1, c2, c3,
input logic[7:0] w, x, y, z,
output logic[7:0] f);
always_comb
begin
if (c1) f = w;
else if (c2) f = x;
else if (c3) f = y;
else f = z;
end
endmodule
Equivalent code
module priority_encoder (input logic c1, c2, c3,
input logic[7:0] w, x, y, z,
output logic[7:0] f);
always_comb
begin
f = z;
if (c3) f = y;
if (c2) f = x;
if (c1) f = w;
end
endmodule
Sequential Logic
Fundamental sequential element edge-triggered Data (or D) flip-flop with
asynchronous reset (active low)
module d_flip_flop (input logic clock, resetn,
input logic d,
output logic q);
always_ff @(posedge clock or negedge resetn) // sensitivity list
begin
if (!resetn)
q <= 1'b0;
else
q <= d;
// this is a non-blocking assignment
end
endmodule
Registers
8-bit register with synchronous enable
module enabled_register (input logic clock, resetn,
input logic en,
input logic[7:0] d,
output logic[7:0] q);
always_ff @(posedge clock or negedge resetn)
begin
if (resetn == 1'b0) // different way to test for active low
q <= 8'b0000_0000;
else
begin
if (en == 1'b1)
q <= d;
end
end
endmodule
Counters
8-bit modulo 201 up counter
module modulo_counter (input logic clock, resetn,
input logic en,
output logic[7:0] count);
logic load;
always_ff @(posedge clock or negedge resetn)
begin
if (!resetn)
count <= 8'h00;
else
begin
if (en)
begin
if (load)
count <= 8'h00;
else
count <= count + 8'd1;
end
end
end
assign load = (count == 8'd200);
endmodule
Counters
Equivalent code explaining
present_count and next_count
module modulo_counter (input logic clock, resetn,
input logic en,
output logic[7:0] count);
logic[7:0] present_count, next_count;
assign count = present_count;
always_ff @(posedge clock or negedge resetn)
begin
if (!resetn)
present_count <= 8'h00;
else
if (en)
present_count <= next_count; // non-blocking assignment
end
always_comb
begin: next_state_logic // this is a label for naming a block
logic load;
// declare a signal only for this block
load = (present_count == 8'd200); // blocking assignment
if (load)
next_count = 8'h00;
else
next_count = present_count + 8'd1;
end
endmodule
11 10 14 15 13 12
gray_code_count
revised
mapping
logic
gray_code_count
Control/data path
Control path
finite state machine (FSM)
Data path
registers, arithmetic units (adders,
multipliers), logic units, shift
registers, counters, comparators,
embedded memories,
Status signals
comparator results, zero detect,
Control signals
synchronous enable, load, shift,
FSM
Up/down 2-bit counter with 0 detect
S0/
z=1
S3/
z=0
S1/
z=0
S2/
z=0
module fsm
logic[1:0] state;
parameter S0 = 2'b00;
parameter S1 = 2'b01;
parameter S2 = 2'b10;
parameter S3 = 2'b11;
always_ff @ (posedge clock or negedge resetn)
begin
if (!resetn)
state <= S0;
else
case (state)
S0: if (w) state <= S1; else state
S1: if (w) state <= S2; else state
S2: if (w) state <= S3; else state
S3: if (w) state <= S0; else state
endcase
end
assign z = (state == S0);
endmodule
<=
<=
<=
<=
S3;
S0;
S1;
S2;
FSM
module fsm
=
=
=
=
S1;
S2;
S3;
S0;
else
else
else
else
next_state
next_state
next_state
next_state
=
=
=
=
S3;
S0;
S1;
S2;
Shift registers
Can be described using a for loop;
or signal concatenation {,,,};
or using the shift operators (e.g., >>)
`define DATA_WIDTH 16
Bit counting
Combinational implementation for loop
`define INPUT_WIDTH 16
`define OUTPUT_WIDTH 5
module bit_count
always_comb
begin : combinational_solution
integer i;
data_out = `OUTPUT_WIDTH'd0;
for (i=0; i <`INPUT_WIDTH; i+=1)
if (data_in[i])
data_out = data_out + `OUTPUT_WIDTH'd1;
end
endmodule
+1
data_in[0]
data_in[1]
data_in[14]
data_in[15]
0
1'b0
1'b1
+1
data_in
0
16
Load
0
0
+1
data_out
5
data_out
Load
SO
Clock
<<
SI
shift register
5
Combinational implementation
Sequential implementation
// sequential implementation that uses one shift register and one counter
module bit_count
logic[`INPUT_WIDTH-1:0] shift_register;
always_ff @(posedge clock, negedge resetn)
begin
if (!resetn) begin
shift_register <= `INPUT_WIDTH'd0;
data_out <= `OUTPUT_WIDTH'd0;
end else begin
if (load) begin
shift_register <= data_in;
data_out <= `OUTPUT_WIDTH'd0;
end else begin
shift_register <= (shift_register << 1); // left shift
if (shift_register[`INPUT_WIDTH-1])
data_out <= data_out + `OUTPUT_WIDTH'd1;
end
end
end
endmodule
Latches
Level sensitive storage elements
module latch_example1 (input logic enable, data_in,
output logic data_out);
always_latch
begin
if (enable)
data_out = data_in;
end
endmodule
Latches
Both case & if statements infer latches
module latch_example4 (input logic c1, c2,
input logic a, b,
output logic f, g);
always_latch
begin
case ({c1,c2})
2'b00: f
2'b01: g
2'b10: f
2'b11: g
endcase
end
=
=
=
=
a;
b;
a | b;
a & b;
endmodule
Latches
What happens if we use incompletely
specified case or if statements with
always_comb?
module latch_incorrect (input logic c1, c2,
input logic a, b,
output logic f);
always_comb
begin
case ({c1,c2})
2'b00: f = a;
2'b01: f = b;
2'b10: f = a | b;
endcase
end
INCORRECT!
(the compiler
should give
an error)
endmodule
=
=
=
f
a;
b;
a | b;
= 1'bx;
CORRECT!
(combinational
logic is further
optimized by
exploiting dont
care conditions)
clock
clock
clock
clock