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
路漫漫其修远兮,吾将上下而求索