An Exploration of Hole Filling Algorithms
An Exploration of Hole Filling Algorithms
An Exploration of Hole Filling Algorithms
Assignment
Assignment to wires uses the assign primitive outside an always block, vis: assign mywire = a & b This is called continuous assignment because mywire is continually updated as a and b change (i.e. it is all combinational logic). Registers are assigned to inside an always block which species where the clock comes from, vis: always @(posedge clock) r<=r+1; The <= assignment operator is none blocking and is performed on every positive edge of clock. Note that if you have whole load of none blocking assignments then they are all updated in parallel. Adding an asynchronous reset: always @(posedge clock or posedge reset) if(reset) r <= 0; else r <= r+1; Note that this will be synthesised to an asynchronous (i.e. independent of the clock) reset where the reset is connected directly to the clear input of the DFF. The blocking assignment operator (=) is also used inside an always block but causes assignments to be performed as if in sequential order. This tends to result in slower circuits, so we do not used it for synthesised circuits.
Operators
Arithmetic: the usual + and - work for add and subtract. Multiply (*) divide (/) and modulus (%) are provided by remember that they may generate substantial hardware which could be quite slow. Shift left (<<) and shift right (>>) operators are available. Some synthesis systems will only shift by a constant amount (which is trivial since it involves no logic). Relational operators: equal (==) not-equal (!=) and the usual < <= > >= Bitwise operators: and (&) or (|) xor () not () Logical operators (where a multi-bit value is false if zero, true otherwise): and (&&) or (||) not (!) Bit reduction unary operators: and (&) or (|) xor () Example, for a 3 bit vector a: &a == a[0] & a[1] & a[2] and |a == a[0] | a[1] | a[2] Conditional operator ? used to multiplex a result Example: (a==3d3) ? formula1 : formula0 For single bit formula, this is equivalent to: ((a==3d3) && formula1) || ((a!=3d3) && formula0)
2b10 : r <= r+2; 2b01 : r <= r+1; default: r <= r; endcase And using the conditional operator (?): always @(posedge clock) r <= (add1 && add2) ? r+3 : add2 ? r+2 : add1 ? r+1 : r; Which because it is a contrived example can be shortened to: always @(posedge clock) r <= r + {add2,add1}; Note that the following would not work: always @(posedge clock) begin if(add1) r <= r + 1; if(add2) r <= r + 2; end The problem is that the none blocking assignments must happen in parallel, so if add1==add2==1 then we are asking for r to be assigned r+1 and r+2 simultaneously which is ambiguous.
a a a a
+ &
b; b; b; b;
Instantiating the above module could be done as follows: wire clk; wire [3:0] data0,data1,sum; simpleClockedALU myFourBitAdder( .clock(clk), .func(0), // constant function .a(data0), .b(data1), .result(sum)); Notes: myFourBitAdder is the name of this instance of the hardware the .clock(clk) notation refers to: .port_name(your_name) which ensures that values are wired to the right place. in this instance the function input is zero, to the synthesis system is likely to simplify the implementation of this instance so that it is only capable of performing an addition (the zero case)
Module declarations
Modules pass inputs and outputs as wires only. If an output is also a register then only the output of that register leaves the module as wires. Example: module simpleClockedALU( input clock, input [1:0] func, input [3:0] a,b, output reg [3:0] result); always @(posedge clock) case(func) 2d0 : result <= a + b; 2d1 : result <= a - b; 2d2 : result <= a & b; default : result <= a b; endcase endmodule Example in pre 2001 Verilog: module simpleClockedALU( clock, func, a, b, result); input clock; input [1:0] func; input [3:0] a,b; output [3:0] result; reg [3:0] result; always @(posedge clock)
Simulation
Example simulation following on from the above instantiation of simpleClockeALU: reg clk; reg [7:0] vals; assign data0=vals[3:0]; assign data1=vals[7:4]; // oscillate clock every 10 simulation units always #10 clk <= !clk; // initialise values initial #0 begin clk = 0; vals=0; // finish after 200 simulation units #200 $finish; end // monitor results always @(negedge clk) $display("%d + %d = %d",data0,data1,sum); Simon Moore