Synthesizeable Verilog Code Examples
Synthesizeable Verilog Code Examples
This page gives FREE synthesizable verilog code examples, block diagrams and timing diagrams of typical digital circuit building blocks.
Last update August 2000
Topics: The following topics are currently covered. (Finished topics have links). 1. Failsafe Synthesis Methodology 2. The .v file structure 3. D type flip flops
D type flip flop D type flip flop with asynchronous reset D type flip flop with synchronous reset D type flip flop with gated clock D type flip flop with data enabled Negative edge triggered D type flip flop
4. Latches 5. Multiplexers
Two input multiplexer using if else Two input multiplexer using ternary operator (?:) Two input multiplexer using case Two input multiplexer using default assignment and if statement Three input priority encoded multiplexer using if else statement Three input priority encoded multiplexer using case statement Three input no priority encoded multiplexer using case statement
6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20.
Comparators Adders Subtractors Multipliers Dividers PLLs (if it is possible!) FIFOs Memories Tristate buffer modelling Counters Verilog Quick Reference 1 Verilog Quick Reference 2 Finite State Machines Blocking (=) versus non blocking (<=) signal assignment and their impact on synthesis Esperan Training
Synthesis Methodology:
l
Synthesis is a contraint driven process - i.e. the synthesis script needs timing constraints Follow the following methodology for best results Draw a simple block diagram, labelling all signals, widths etc. Draw a timing diagram with as much detail as possible Code the HDL according to the synthesizable template Do a quick, low effort, compile- just to see if it is synthesizable compare this to the block diagram (look at the inference report, check the number of flip flops, check for latches). Simulate and compare with the timing diagram If your design doesn't meet timing by more than 10% of the clock period, then go back to the code. If you are within 10% of the clock period, then try a different compile strategy.
A good template for your verilog files is shown below with an example given afterwards. This is not taken from the Language reference manual. // timescale directive tells the simulator the base units and precision of the simulation `timescale 1 ns / 10 ps module <name> (<input and outputs>); // parameter declarations parameter <parameter_name> = <parameter value>; // Input output declarations input <in1>; input<in2>//singlebitinputs input[<msb>:<lsb>]<in3>//abusinput // internal signal register type declaration - register types (only assigned within always statements). reg <register variable 1>; reg [<msb>:<lsb>] <register variable 2>; // internal signal. net type declaration - (only assigned outside always statements) wire <net variable 1>; // hierarchy - instantiating another module <reference name> <instance name> ( .pin1(net1), .pin2(net2), . . . .pinn(netn) ) // synchronous procedures always @ (posedge <clock>) begin . . . end // combinatinal procedures always @ (signal1 or signal2 or signal3) begin . . . end assign <net variable> = <combinational logic>; endmodule D Type Flip Flops: Two things to note about inferring flip flops:
l l
Non blocking signal assignment (<=) should always be used The sensitivity list must have the keyword posedge or negedge. (also for resets)
D type flip flop with asynchronous reset reg q; always @ (posedge clk or posedge reset) if(reset) q<=1'b0 else q<=d
D type flip flop with synchronous reset reg q; always @ (posedge clk) if(reset) q<=1'b0 else q<=d
D type flip flop with gated clock reg q; wire gtd_clk = enable && clk; always @ (posedge gtd_clk) q<=d
Data enbled D type flip flop reg q; always @ (posedge clk) if(enable) q<=d
Negative edge triggered D type flip flop reg q; always @ (negedge clk) q<=d
Multiplexers Two input multiplexer (using if else) reg y; always @ (a or b or select) if(select) y=a else y=b
Two input multiplexer (using ternary operator ?:) wire t = (select ? a : b);
Two input multiplexer (using case statement) reg w; // mux version 3 always @ (a or b or select) case(select) 1'b1:w=a default:w=b endcase
Two input multiplexer (using default assignment and if) reg p; // mux version 4 always @ (a or b or select) begin p=b if(select) p=a end
Three input priority encoded mux multiplexer (using if else) reg q; always @ (a or b or c or select2) if(select2==2'b00) q=a else if(select2==2'b01) q=b else q=c
Three input priority encoded mux multiplexer (using case) reg r; // Priority encoded mux, version 2 always @ (a or b or c or select2) begin r=c case(select2) 2'b00:r=a 2'b01:r=b endcase end
Three input multiplexer with no priority (using case) reg s; always @ (a or b or c or select2) begin case(select2)//synopsysparallel_case 2'b00:s=a 2'b01:s=b default:s=c endcase end
Comparator (using assign) module comparator1 (a,b,c); inputa inputb output c; assign c = (a == b); endmodule
Comparator (using always) module comparator2 (a,b,c); inputa inputb output c; regc always @ (a or b) if(a==b) c=1'b1 else c=1'b0 endmodule
Finite State Machines A full example of a state machine and associated test bench The state machine The state machine test bench The following is a simple four state finite state machine. The methodology for writing finite state machines is as follows: 1. Draw a state diagram. Label all conditions, label all output values. Label the state encoding. 2. Use parameter to encode the states as in the example. 3. Use two processes or always statements- one sequential and one combinational. See the example. 4. The state machine is normally resettable _ choose synchronous or asynchronous. 5. The combinational process normally has one big case statement in it. Put default values at the beginning. There are a couple of neat things about the example. We are using parameters is the test bench and passing them to the state machine using parameter passing We are using tasks to control the flow of the testbench We are using hierarchical naming to access the state variable in the state machine from the test bench. Finally we are using test bench messages which allow us to monitor the current state from the simulation waveform viewer (assuming we change the bus radix of the 'message' to ascii.
// -------------------------------------------// //STATEMACHINE // // -------------------------------------------module state_machine(sm_in,sm_clock,reset,sm_out); parameteridle=2'b00 parameterread=2'b01 parameter write = 2'b11; parameterwait=2'b10 input sm_clock; input reset; input sm_in; output sm_out; reg [1:0] current_state, next_state;
always @ (current_state or sm_in) begin //defaultvalues sm_out=1'b1 next_state=current_state case(current_state) idle: sm_out=1'b0 if(sm_in) next_state=2'b11 write: sm_out=1'b0 if(sm_in==1'b0) next_state=2'b10 read: if(sm_in==1'b1) next_state=2'b01 wait: if(sm_in==1'b1) next_state=2'b00 endcase end endmodule
// -------------------------------------------// //TESTBENCH // // -------------------------------------------module testbench; // parameter declaration section // ... parameteridle_state=2'b00 parameterread_state=2'b01 parameter write_state = 2'b11; parameterwait_state=2'b10 // testbench declaration section reg [500:1] message; reg [500:1] state_message; reg in1; reg clk; reg reset; wire data_mux; // instantiations state_machine #(idle_state, read_state, write_state, wait_state)st_mac( .sm_in(in1), .sm_clock(clk), .reset(reset), .sm_out(data_mux) ) // monitor section always @ (st_mac.current_state) case(st_mac.current_state) idle_state:state_message="idle" read_state:state_message="read" write_state:state_message="write" wait_state:state_message="wait" endcase // clock declaration initial clk = 1'b0; always #50 clk = ~clk; // tasks task reset_cct;
begin @(posedgeclk) message="reset" @(posedgeclk) reset=1'b1 @(posedgeclk) reset=1'b0 @(posedgeclk) @(posedgeclk) end endtask task change_in1_to; inputa begin message = "change in1 task"; @ (posedge clk); in1 = a; end endtask // main task calling section initial begin message = "start"; reset_cct; change_in1_to(1'b1); change_in1_to(1'b0); change_in1_to(1'b1); change_in1_to(1'b0); change_in1_to(1'b1); @ (posedge clk); @ (posedge clk); @ (posedge clk); $stop; end endmodule
Please mail any comments or coding queries to [email protected] Last updated: August 23, 2000