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

posted on 2011-04-13 17:47  齐威王  阅读(1084)  评论(0编辑  收藏  举报

导航