1module full_adder(2 input a, b, cin,3 output s, cout);4 assign s = a ^ b ^ cin;5 assign cout = (a&b) |6 (cin&(a^b));7endmodule1module counter(2 input clk, rst,3 output reg [3:0] count);4 always @(posedge clk)5 if (rst) count <= 0;6 else count <= count+1;7endmoduleabcinscoutFULL_ADDER01XOR01XOR01ANDAND01OR01clkrstDQCOUNTER+1ADD 101842101010101COUNT0010000
Highlighted code line: the part of the code this step is about; its gates light with itLamps: a glowing lamp is a 1, a dark one a 0 (flip-flop weights 8 4 2 1)Lit wire with moving dashes: it carries a 1Token: a value travelling round the counter loop, or a piece of code flying to the gate it becomesTwo Verilog modules beside the circuits they describe. assign lines become gates that work all the time (combinational logic); an always @(posedge clk) block becomes flip-flops that change only at a rising clock edge (sequential logic). Verilog was standardised as IEEE 1364 (last edition 1364-2005). Since 2009 it is part of SystemVerilog, IEEE 1800, which adds features for testing designs. The other widely used HDL is VHDL, IEEE 1076. Synthesis reads the HDL and writes a netlist: a list of gates and flip-flops and the wires between them. Yosys is an open-source synthesis tool; FPGA and chip vendors ship their own. The netlist then goes on to place and route.

Describing a circuit

  1. A chip holds millions of gates, far too many to draw by hand. So engineers write a description in a hardware description language (HDL). The Verilog card on the left describes the full adder circuit on the right.

Combinational logic: assign

Sequential logic: always

From text to gates

Code and circuit

;; step 1/9 · describe
;; about: full_adder code, XOR a^b, XOR ^cin, AND a&b, AND cin&p, OR, Inputs, Output s, Output cout
Verilog: IEEE 1364, now part of SystemVerilog (IEEE 1800)

module full_adder(
  input  a, b, cin,
  output s, cout);
  assign s = a ^ b ^ cin;
  assign cout = (a&b) |
    (cin&(a^b));
endmodule

The card is text. A tool reads it and builds
the gates beside it.

assign is a continuous assignment: its left side is driven by the expression all the time, like a wire soldered to a gate's output. Because every assign is working at once, their order in the file does not matter (Harris and Harris, chapter 4). Inside always @(posedge clk), write <= (nonblocking). Every right-hand side is read first, with the values from just before the edge, and all the flip-flops update together. Mixing up = and <= is a classic bug (Cummings, SNUG 2000).