CS641 class 22  More on Verilog

handout on iverilog netlists

 

Always statement in Verilog

Always statement: uses procedural code, like initial, but does it over and over, not just once.

Left-hand side much be a reg

(recall rule for assign: lhs must be type wire)

 

reg A;

always @ (B or C)

  A = B & C;

 

works like assign A = B & C

i.e., another way to specify combinational circuitry

 

The execution of a procedural statement is triggered by:

·          A value change on a wire

·         The occurrence of a named event

always @ (B or C) begin // controlled by any value change in B or C

  X = B & C;

end

always @(posedge Clk) Y <= B&C; // controlled by positive edge of Clk

always @(negedge Clk) Z <= B&C; // controlled by negative edge of Clk

 

We can use “always” to model the snapshot behavior of D FF’s and registers

 

What is the behavior of a D-flipflop ?

During every positive clock edge, the input is transferred to the output

See pg. C-53:

 

module DFF(clock,D,Q,Qbar);

 input clock, D;

 output reg Q; // Q is a reg since it is assigned in an always block

 output Qbar;

 assign Qbar = ~ Q; // Qbar is always just the inverse of Q

 always @(posedge clock) // perform actions whenever the  clock rises

  Q = D;

endmodule

 

Also see the Berkeley 61c handout for another version of DFF, with a RESET.

No testbed here, but we could modify the one for the RSFF.

This is a case where the reg turns into a real register in the resulting circuit.  It is needed because the Qint reg can hold values that, because of the assigns to Q and Qbar, can be observed after the time they are set. Actually, it’s the first time we’ve seen a reg inside a module.

Finding out what components are used in the circuit: do “synthesis”, gen the netlist—see handout.

For synthesis, need to use iverilog on sf06, version .8x: later versions have lost synthesis capability!

FPGA: field programmable gate array: circuits be “programmed” i.e. built, by a machine from a program.

Verilog—>synthesis--> FPGA---> working circuit

Note we can add a reg to a module without causing a real register:

sf06.cs.umb.edu$ more mynandreg.v

// nand gate with “extra” reg that doesn’t

// cause a register in the circuit

module mynand(in0, in1, out);

  input in0, in1;

  output out;

  reg   t;

  assign out = t;

 

  always @(in0 or in1)

    t = ~(in0 & in1);

endmodule

 

This has the same gates as mynand in its netlist.

Also the design using AND and NOT gates.

 

Here iverilog is smart enough to see that t is just passing its value through to out, so a register isn’t needed in the circuit.

 

With verilog, we can design with gates or Boolean expressions, and get working circuits out.

 

A Register in Verilog

 

Back to W’s 61c tutorial, look at pg.13, reg4

// positive edge-triggered,

// synchrounous active-high reset.

module reg4 (CLK,Q,D,RST);

  input [3:0] D;

  input CLK, RST;

  output [3:0] Q;

  reg [3:0] Q;

  always @ (posedge CLK)

    if (RST) #1 Q = 0; else #1 Q = D;

endmodule // reg4

 

This reg will turn into a register, like the one in the DFF, to hold the sampled Q value for output.

 

We could write a TB for this like our old RSFF, setting signals manually at each point in time:

...

reg4 myreg(.CLK(CLK), .Q(q), .D(d), .RST(rst));

 

initial

  begin

#0 rst = 1’b1; CLK =0;

#5 CLK =1;        // expect new q = 0 at time +1

#5 CLK =0; rst =0; d=4’b0101;   // changing rst and d while clk=0

#5 CLK =1;        

#5 CLK =0; rst =0; d=4’b0111;   // changing rst and d while clk=0

#5 CLK =1;        

...

 

But this is boring, and get too many lines with monitor if it includes clk.

 

Using a Clock signal in Verilog, with its own code separate from the rest of the code

 

See idea on pg. 13, 15: get a clock going in the testbed module

 

reg4 myreg(.CLK(CLK), .Q(q), .D(d), .RST(rst));

 

initial

 begin

  CLK=1’b0;

  forever

   #5 CLK = ˜CLK;

 end

initial

begin

#0 rst = 1’b1; // changing rst and d while clk=0

#10 rst =0; d=4’b0101;   // changing rst and d while clk=0

#20 d=4’b0111;   //...

$stop

 

The Accumulator Circuit

pg 14: The accumulator circuit we discussed a while ago, now done in Verilog

Uses reg4 and also add4: we’ll get back to adders soon. Of course we could just write it as an expression

  assign sum = x + y;

and let Verilog figure out something. 

 

State Machines

parity checker: input 1001, output 0, input 10011, output 1, etc: even or odd number of 1s.

 

parityChecker: Note bug, need “xor #1 (...)”

 

Idea of buffer gate, needed here for Verilog.  OUT = IN

 

Could use reg instead of DFF:

 

reg state;

always (@posedge CLK)

  state = RST?0:IN^state;

assign out = state;

 

This will turn into a register/FF in the circuit

instead of ?, can use if/else or case. See pg. C-25 for case ( <= ensures parallel assigns, but not necessary here I think)

case statements are like C switches that don’t need breaks because they don’t fall from one case to another.

 

Nice testbed on pg. 17, showing how separate clock simplifies the test code. We only need to say what to do at 0, 10, 20,..., knowing that the clock will rise at 5, 15, 25, ..., well away from any delays in the system.

 

Note how we have to drive the system into each state and then out from there. Can be tricky.  Can start over from initial state as needed.

 

This is simpler but similar to the early example of a finite machine to recognize 3 1s in a row.

Finite State Machine Example from Sequential Circuits Handout: 3 ones…

To do this, the system must be able to count ones up to 3, then start over.  But it only needs memory for counts up to 2, because it can handle the last instance “on the fly”.  So it only needs 3 states, S0, S1, S2 for how many ones already seen, and if in state S2 and sees another 1, report output=1.

Note fix from handout!  S2 --> S0 on input = 1.

Need reg state to hold 0, 1, 2

Need to treat two ways out of each of three states--

Can set up case (state) inside always (@posedge clk), then in one case, tread input = 0 and input = 1 subcases.

 

Like reset of parityChecker, it would be good to have an init capability to force the system to state 0.

 

ThreeOnesChecker(OUT, IN, CLK, RST): same ports as parityChecker

Testbed: start with RST, then check self-loop, then 1 to go to S1, then 0 to go back to S0, then 1 to S1 again, then 1 to S2, then 0 to S0, then 1, and 1 again to get back to S2, then 1 to S0 seeing 1 output.

 

Adders

 

OK, thinking back, we had worked on building an adder

 

Clearly w can now build a 1-bit adder

  module add1bit(a, b, c, s, c)

 

The challenge comes in wiring up 4 of these to make add4. Cover next time