FPGA Prototyping By Verilog Examples第七章 阻塞和非阻塞赋值
阻塞和非阻塞赋值
// Listing 7.1
module and_block
(
input wire a, b, c,
output reg y
);
always @*
begin
y = a;
y = y & b;
y = y & c;
end
endmodule

// Listing 7.2
module and_nonblock
(
input wire a, b, c,
output reg y
);
always @*
begin // y$_{entry}$ = y
y <= a; // y$_{exit}$ = a
y <= y & b; // y$_{exit}$ = y$_{entry}$ \& b
y <= y & c; // y$_{exit}$ = y$_{entry}$ \& c
end // y = y$_{exit}$
endmodule

// Listing 7.3
module eq1_block
(
input wire i0, i1,
output reg eq
);
reg p0, p1;
always @(i0,i1) // only i0 and i1 in sensitivity list
// the order of statements is important
begin
p0 = ~i0 & ~i1;
p1 = i0 & i1;
eq = p0 | p1;
end
endmodule

// Listing 7.4
module eq1_non_block
(
input wire i0, i1,
output reg eq
);
reg p0, p1;
always @(i0,i1,p0,p1) // p0, p1 also in sensitivity list
// the order of statements is not important
begin // p0$_{entry}$ = p0; p1$_{entry}$ = p1;
p0 <= ~i0 & ~i1; // p0$_{exit}$ = ~i0 \& ~i1;
p1 <= i0 & i1; // p1$_{exit}$ = i0 \& i1
eq <= p0 | p1; // eq$_{exit}$ = p0$_{entry}$ | p1$_{entry}$
end // eq = eq$_{exit}$; p0 = p0$_{exit}$; p1 = p1$_{exit}$;
endmodule

// Listing 7.5
module ab_ff_2seg
(
input wire clk,
input wire a, b,
output reg q
);
reg q_next;
// D FF
always @(posedge clk)
q <= q_next;
// combinational circuit
always @*
q_next = a & b;
endmodule

// Listing 7.6
module ab_ff_all
(
input wire clk,
input wire a, b,
output reg q0, q1, q2, q3, q4, q5
);
reg ab0, ab1, ab2, ab3, ab4, ab5;
// attempt 0
always @(posedge clk)
begin
ab0 = a & b;
q0 <= ab0;
end
// attempt 1
always @(posedge clk)
begin // ab1$_{entry}$ = ab1; q1$_{entry}$ = q1;
ab1 <= a & b; // ab1$_{exit}$ = a \& b
q1 <= ab1; // q1$_{exit}$ = ab1$_{entry}$
end // ab1 = ab1$_{exit}$; q1 = q1$_{exit}$
// attempt 2
always @(posedge clk)
begin
ab2 = a & b;
q2 = ab2;
end
// attempt 3 (switch the order of attempt 0)
always @(posedge clk)
begin
q3 <= ab3;
ab3 = a & b;
end
// attempt 4 (switch the order of attempt 1)
always @(posedge clk)
begin // ab4$_{entry}$ = ab4; q4$_{entry}$ = q4;
q4 <= ab4; // q4$_{exit}$ = ab4$_{entry}$
ab4 <= a & b; // ab4$_{exit}$ = a \& b
end // ab4 = ab4$_{exit}$; q4 = q4$_{exit}$
// attempt 5 (switch the order of attempt 2)
always @(posedge clk)
begin
q5 = ab5;
ab5 = a & b;
end
endmodule

// Listing 7.7
module bin_counter_merge
#(parameter N=8)
(
input wire clk, reset,
output wire max_tick,
output wire [N-1:0] q
);
//signal declaration
reg [N-1:0] r_next, r_reg;
// body
// register and next-state logic
always @(posedge clk, posedge reset)
if (reset)
r_reg <= 0; // {N{1b'0}}
else
begin
// next-state logic
r_next = r_reg + 1;
// register
r_reg <= r_next;
end
// output logic
assign q = r_reg;
assign max_tick = (r_reg==2**N-1) ? 1'b1 : 1'b0;
endmodule


NOTE:
assign max_tick = (r_reg==2**N-1) ? 1'b1 : 1'b0;
必须放在always block 外面;如果
assign max_tick = (r_reg==2**N-1) ? 1'b1 : 1'b0;
这句放在always block块语句里面的话,max_tick就要被DFF多打一拍,延时一个时钟周期。
将这两句
// next-state logic r_next = r_reg + 1; // register r_reg <= r_next;
合成一句就有下面的写法
// Listing 7.8
module bin_counter_terse
#(parameter N=8)
(
input wire clk, reset,
output wire max_tick,
output reg [N-1:0] q
);
// body
always @(posedge clk, posedge reset)
if (reset)
q <= 0;
else
q <= q + 1;
// output logic
assign max_tick = (q==2**N-1) ? 1'b1 : 1'b0;
endmodule

// Listing 7.9
module univ_bin_counter_merged
#(parameter N=8)
(
input wire clk, reset,
input wire syn_clr, load, en, up,
input wire [N-1:0] d,
output wire max_tick, min_tick,
output reg [N-1:0] q
);
// body
// register and next-state logic
always @(posedge clk, posedge reset)
if (reset)
q <= 0; //
else if (syn_clr)
q <= 0;
else if (load)
q <= d;
else if (en & up )
q <= q + 1;
else if (en & ~up )
q <= q - 1;
// no else branch since q <= q is implicitly implied
// output logic
assign max_tick = (q==2**N-1) ? 1'b1 : 1'b0;
assign min_tick = (q==0) ? 1'b1 : 1'b0;
endmodule
// Listing 7.10
module fsm_eg_merged
(
input wire clk, reset,
input wire a, b,
output wire y0, y1
);
// symbolic state declaration
parameter [1:0] s0 = 2'b00,
s1 = 2'b01,
s2 = 2'b10;
// signal declaration
reg [1:0] state_reg;
// state register and next-state logic
always @(posedge clk, posedge reset)
if (reset)
state_reg <= s0;
else
case (state_reg)
s0: if (a)
if (b)
state_reg <= s2;
else
state_reg <= s1;
else
state_reg <= s0;
s1: if (a)
state_reg <= s0;
else
state_reg <= s1;
s2: state_reg <= s0;
default state_reg <= s0;
endcase
// Moore output logic
assign y1 = (state_reg==s0) || (state_reg==s1);
// Mealy output logic
assign y0 = (state_reg==s0) & a & b;
endmodule
// Listing 7.20
module exp1
(
input wire clk,
input wire x0, y0, z0,
output reg x3, y3, z3
);
reg x1, x2, y1, y2, z1, z2;
// attempt 1
always @(posedge clk)
begin
x1 <= x0;
x2 <= x1;
x3 <= x2;
end
// attempt 2
always @(posedge clk)
begin
y1 = y0;
y2 = y1;
y3 = y2;
end
// attempt 3
always @(posedge clk)
begin
z1 = z0;
z3 = z2;
z2 = z1;
end
endmodule
路漫漫其修远兮,吾将上下而求索
浙公网安备 33010602011771号