├── 2 Verilog Language ├── 2.1 Basics │ ├── 2.1.3 inverter.v │ ├── 2.1.1 simple_wire.v │ ├── 2.1.4 and_gate.v │ ├── 2.1.6 xnor_gate.v │ ├── 2.1.5 nor_gate.v │ ├── 2.1.2 four_wires.v │ ├── 2.1.8 7458_chip.v │ └── 2.1.7 declaring_wires.v ├── 2.5 More Verilog Features │ ├── 2.5.2 reduction.v │ ├── 2.5.3 gate100.v │ ├── 2.5.1 conditional.v │ ├── 2.5.5 popcount255.v │ ├── 2.5.4 vector100r.v │ ├── 2.5.6 adder100i.v │ └── 2.5.7 bcdadd100.v ├── 2.2 Vectors │ ├── 2.2.8 replication_operator.v │ ├── 2.2.3 vector_part_select.v │ ├── 2.2.2 vectors_in_more_detail.v │ ├── 2.2.6 vector_concatenation_operator.v │ ├── 2.2.5 four-input_gates.v │ ├── 2.2.1 vectors.v │ ├── 2.2.9 more_replication.v │ ├── 2.2.4 bitwise_operators.v │ └── 2.2.7 vector_reversal_1.v ├── 2.3 Modules Hierachy │ ├── 2.3.4 module_shift.v │ ├── 2.3.2 module_pos.v │ ├── 2.3.3 module_name.v │ ├── 2.3.6 module_add.v │ ├── 2.3.9 module_addsub.v │ ├── 2.3.7 module_fadd.v │ ├── 2.3.5 module_shift8.v │ ├── 2.3.8 module_cseladd.v │ └── 2.3.1 module.v └── 2.4 Procedures │ ├── 2.4.1 alwaysblock1.v │ ├── 2.4.6 always_case2.v │ ├── 2.4.2 alwaysblock2.v │ ├── 2.4.3 always_if.v │ ├── 2.4.4 always_if2.v │ ├── 2.4.8 always_nolatches.v │ ├── 2.4.5 always_case.v │ └── 2.4.7 always_casez.v ├── 1 Getting Started ├── 1.1 step_one.v └── 1.2 output_zero.v ├── 3 Circuit ├── 3.1 Combinational Logic │ ├── 3.1.1 Basic Gates │ │ ├── 3.1.1.2 gnd.v │ │ ├── 3.1.1.1 wire.v │ │ ├── 3.1.1.10 simple circuit A.v │ │ ├── 3.1.1.11 simple circuit B.v │ │ ├── 3.1.1.3 another gate.v │ │ ├── 3.1.1.4 two gates.v │ │ ├── 3.1.1.6 7420 chip.v │ │ ├── 3.1.1.15 3-bit population count.v │ │ ├── 3.1.1.14 thermostat.v │ │ ├── 3.1.1.17 even longer vectors.v │ │ ├── 3.1.1.9 two-bit equality.v │ │ ├── 3.1.1.13 ring or vibrate.v │ │ ├── 3.1.1.5 more logic gates.v │ │ ├── 3.1.1.8 truth tables.v │ │ ├── 3.1.1.12 combine circuits A and B.v │ │ └── 3.1.1.16 gates and vectors.v │ ├── 3.1.2 Multiplexers │ │ ├── 3.1.2.1 2-to-1 multiplexer.v │ │ ├── 3.1.2.2 2-to-1 bus multiplexer.v │ │ ├── 3.1.2.4 256-to-1 4-bit multiplexer.v │ │ ├── 3.1.2.4 256-to-1 multiplexer.v │ │ └── 3.1.2.3 9-to-1 multiplexer.v │ ├── 3.1.4 Karnaugh Map to Circuit │ │ ├── 3.1.4.6 kmap5.v │ │ ├── 3.1.4.1 kmap1.v │ │ ├── 3.1.4.7 kmap6.v │ │ ├── 3.1.4.4 kmap4.v │ │ ├── 3.1.4.3 kmap3.v │ │ ├── 3.1.4.2 kmap2.v │ │ ├── 3.1.4.8 kmap with a multiplexer.v │ │ └── 3.1.4.5 minimum SOP and POS.v │ └── 3.1.3 Arithmetic Circuits │ │ ├── 3.1.3.1 half adder.v │ │ ├── 3.1.3.2 full adder.v │ │ ├── 3.1.3.6 100-bit binary adder.v │ │ ├── 3.1.3.5 signed addition overflow.v │ │ ├── 3.1.3.7 4-digit BCD adder.v │ │ ├── 3.1.3.3 3-bit binary adder.v │ │ └── 3.1.3.4 adder.v ├── 3.2 Sequential Logic │ ├── 3.2.1 Latches and Flip-Flops │ │ ├── 3.2.1.10 DFF_gate.v │ │ ├── 3.2.1.7 D Latch.v │ │ ├── 3.2.1.2 8-bit DFF.v │ │ ├── 3.2.1.4 DFF_reset2.v │ │ ├── 3.2.1.9 DFF_r.v │ │ ├── 3.2.1.3 DFF_reset.v │ │ ├── 3.2.1.8 DFF_ar.v │ │ ├── 3.2.1.16 Dual Edge Detector.v │ │ ├── 3.2.1.11 MUX and DFF.v │ │ ├── 3.2.1.13 DFFs and Gates.v │ │ ├── 3.2.1.15 Edge Detector.v │ │ ├── 3.2.1.14 Truth Table.v │ │ ├── 3.2.1.1 DFF.v │ │ ├── 3.2.1.12 MUX and DFF n.v │ │ ├── 3.2.1.6 DFF_byteEnable.v │ │ ├── 3.2.1.17 Dual-edge triggered FF.v │ │ ├── 3.2.1.5 DFF_areset.v │ │ └── 3.2.1.17 Edge Capture.v │ ├── 3.2.5 Finite State Machines │ │ ├── 3.2.5.31 Q2b one-hot FSM equations.v │ │ ├── 3.2.5.28 Q6c FSM one-hot next-state logic.v │ │ ├── 3.2.5.27 Q6b FSM next-state logic.v │ │ ├── 3.2.5.23 Q5b serial 2s complementer Mealy.v │ │ ├── 3.2.5.22 Q5a serial 2s complementer Moore.v │ │ ├── 3.2.5.26 Q3c FSM logic.v │ │ ├── 3.2.5.25 Q3b FSM5.v │ │ ├── 3.2.5.29 Q6 FSM7.v │ │ ├── 3.2.5.30 Q2a FSM8.v │ │ ├── 3.2.5.3 FSM2_ar.v │ │ ├── 3.2.5.14 One-hot FSM.v │ │ ├── 3.2.5.32 Q2a FSM9.v │ │ ├── 3.2.5.17 serial receiver.v │ │ ├── 3.2.5.15 PS2 packet parser.v │ │ ├── 3.2.5.16 PS2 packet parser and datapath.v │ │ ├── 3.2.5.11 Lemmings 2.v │ │ ├── 3.2.5.2 FSM1_r.v │ │ ├── 3.2.5.20 sequence recognition.v │ │ ├── 3.2.5.18 serial receiver and datapath.v │ │ ├── 3.2.5.12 Lemmings 3.v │ │ ├── 3.2.5.24 Q3a FSM4.v │ │ ├── 3.2.5.19 serial receiver with parity checking.v │ │ ├── 3.2.5.10 Lemmings 1.v │ │ ├── 3.2.5.1 FSM1_ar.v │ │ ├── 3.2.5.13 Lemmings 4.v │ │ └── 3.2.5.21 Q8 Mealy FSM.v │ ├── 3.2.2 Counters │ │ ├── 3.2.2.2 decade counter.v │ │ ├── 3.2.2.3 decade counter2.v │ │ ├── 3.2.2.5 slow decade counter.v │ │ ├── 3.2.2.4 counter 1-to-12.v │ │ ├── 3.2.2.1 4-bit BC.v │ │ ├── 3.2.2.6 counter 1000.v │ │ ├── 3.2.2.7 4-digit decimal counter.v │ │ └── 3.2.2.8 12-hour clock.v │ ├── 3.2.4 More Circuits │ │ ├── 3.2.4.2 Rule 110.v │ │ ├── 3.2.4.1 Rule 90.v │ │ └── 3.2.4.3 Conway's Game of Life.v │ └── 3.2.3 Shift Registers │ │ ├── 3.2.3.7 Shift Register 1.v │ │ ├── 3.2.3.5 3-bit LFSR.v │ │ ├── 3.2.3.1 4-bit SR.v │ │ ├── 3.2.3.2 left_right rotator.v │ │ ├── 3.2.3.3 left_right_arithmetic_shift.v │ │ ├── 3.2.3.6 32-bit LFSR.v │ │ ├── 3.2.3.8 Shift Register 2.v │ │ ├── 3.2.3.9 3-input LUT.v │ │ └── 3.2.3.4 5-bit LFSR.v └── 3.3 Building Larger Circuits │ ├── 3.3.1 counter with period 1000.v │ ├── 3.3.2 4-bit SR and down counter.v │ ├── 3.3.4 FSM Enable SR.v │ ├── 3.3.3 FSM 1101 sequence recognizer.v │ ├── 3.3.7 One-hot logic equations.v │ ├── 3.3.5 FSM Complete FSM.v │ └── 3.3.6 Complete Timer.v ├── 4 Verification Reading Simulations ├── 4.1 Finding bugs in code │ ├── 4.1.2 NAND.v │ ├── 4.1.3 MUX2.v │ ├── 4.1.4 Add_SUB.v │ ├── 4.1.1 MUX1.v │ └── 4.1.5 Case statement.v └── 4.2 Build a circuit from a simulation waveform │ ├── 4.2.7 Sequential circuit 7.v │ ├── 4.2.4 Combinational circuit 4.v │ ├── 4.2.2 Combinational Circuit 2.v │ ├── 4.2.3 Combinational Circuit 3.v │ ├── 4.2.1 Combinational Circuit 1.v │ ├── 4.2.10 Sequential circuit 7.v │ ├── 4.2.8 Sequential circuit 7.v │ ├── 4.2.9 Sequential circuit 7.v │ ├── 4.2.5 Combinational Circuit 5.v │ └── 4.2.6 Combinational Circuit 6.v ├── 5 Verification Writing Testbenches ├── 5.3 AND Gate.v ├── 5.2 Testbench1.v ├── 5.1 Clock.v ├── 5.5 TFF.v └── 5.4 Testbench2.v ├── README.md └── Tips.md /2 Verilog Language/2.1 Basics/2.1.3 inverter.v: -------------------------------------------------------------------------------- 1 | module top_module( input in, output out ); 2 | assign out = ~in; 3 | endmodule 4 | -------------------------------------------------------------------------------- /2 Verilog Language/2.1 Basics/2.1.1 simple_wire.v: -------------------------------------------------------------------------------- 1 | module top_module( input in, output out ); 2 | assign out = in; 3 | endmodule 4 | -------------------------------------------------------------------------------- /1 Getting Started/1.1 step_one.v: -------------------------------------------------------------------------------- 1 | module top_module( output one ); 2 | 3 | // Insert your code here 4 | assign one = 1'b1; 5 | 6 | endmodule -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.1 Basic Gates/3.1.1.2 gnd.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | output out); 3 | assign out = 1'b0; 4 | endmodule 5 | -------------------------------------------------------------------------------- /1 Getting Started/1.2 output_zero.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | output zero 3 | );// Module body starts after semicolon 4 | assign zero = 1'o2; 5 | endmodule -------------------------------------------------------------------------------- /2 Verilog Language/2.1 Basics/2.1.4 and_gate.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input a, 3 | input b, 4 | output out ); 5 | assign out = a&b; 6 | endmodule 7 | -------------------------------------------------------------------------------- /2 Verilog Language/2.1 Basics/2.1.6 xnor_gate.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input a, 3 | input b, 4 | output out ); 5 | assign out = ~a^b; 6 | endmodule 7 | -------------------------------------------------------------------------------- /2 Verilog Language/2.1 Basics/2.1.5 nor_gate.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input a, 3 | input b, 4 | output out ); 5 | assign out = ~(a|b); 6 | endmodule 7 | -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.1 Basic Gates/3.1.1.1 wire.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input in, 3 | output out); 4 | assign out = in; 5 | endmodule 6 | 7 | -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.1 Basic Gates/3.1.1.10 simple circuit A.v: -------------------------------------------------------------------------------- 1 | module top_module (input x, input y, output z); 2 | assign z = (x^y) & x; 3 | endmodule 4 | -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.1 Basic Gates/3.1.1.11 simple circuit B.v: -------------------------------------------------------------------------------- 1 | module top_module (input x, input y, output z); 2 | assign z = ~(x^y); 3 | endmodule 4 | -------------------------------------------------------------------------------- /2 Verilog Language/2.5 More Verilog Features/2.5.2 reduction.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input [7:0] in, 3 | output parity); 4 | assign parity = ^ in; 5 | endmodule 6 | -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.2 Multiplexers/3.1.2.1 2-to-1 multiplexer.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input a, b, sel, 3 | output out ); 4 | assign out = (sel==1)?b:a; 5 | endmodule -------------------------------------------------------------------------------- /2 Verilog Language/2.2 Vectors/2.2.8 replication_operator.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input [7:0] in, 3 | output [31:0] out );// 4 | 5 | assign out = {{24{in[7]}},{in}}; 6 | 7 | endmodule 8 | -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.1 Basic Gates/3.1.1.3 another gate.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input in1, 3 | input in2, 4 | output out); 5 | assign out = ~ (in1|in2); 6 | endmodule 7 | -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.4 Karnaugh Map to Circuit/3.1.4.6 kmap5.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input [4:1] x, 3 | output f ); 4 | assign f = ~x[1]&x[3] | x[1]&x[2]&x[4]; 5 | endmodule 6 | -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.3 Arithmetic Circuits/3.1.3.1 half adder.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input a, b, 3 | output cout, sum ); 4 | assign cout = a&b; 5 | assign sum = a^b; 6 | endmodule 7 | -------------------------------------------------------------------------------- /2 Verilog Language/2.2 Vectors/2.2.3 vector_part_select.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input [31:0] in, 3 | output [31:0] out );// 4 | 5 | assign {out[7:0],out[15:8],out[23:16],out[31:24]} = in; 6 | 7 | endmodule 8 | -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.1 Basic Gates/3.1.1.4 two gates.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input in1, 3 | input in2, 4 | input in3, 5 | output out); 6 | assign out = in3 ^ ~(in1^in2); 7 | endmodule 8 | -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.4 Karnaugh Map to Circuit/3.1.4.1 kmap1.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input a, 3 | input b, 4 | input c, 5 | output out ); 6 | assign out = (a | b | c); 7 | endmodule 8 | -------------------------------------------------------------------------------- /2 Verilog Language/2.3 Modules Hierachy/2.3.4 module_shift.v: -------------------------------------------------------------------------------- 1 | module top_module ( input clk, input d, output q ); 2 | wire q1,q2; 3 | my_dff d1(clk,d,q1); 4 | my_dff d2(clk,q1,q2); 5 | my_dff d3(clk,q2,q); 6 | endmodule -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.2 Multiplexers/3.1.2.2 2-to-1 bus multiplexer.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input [99:0] a, b, 3 | input sel, 4 | output [99:0] out ); 5 | assign out = (sel)? b:a; 6 | endmodule 7 | -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.2 Multiplexers/3.1.2.4 256-to-1 4-bit multiplexer.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input [255:0] in, 3 | input [7:0] sel, 4 | output out ); 5 | assign out = in[sel]; 6 | endmodule 7 | -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.4 Karnaugh Map to Circuit/3.1.4.7 kmap6.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input [4:1] x, 3 | output f 4 | ); 5 | assign f = (~x[1]&x[3])|(~x[2]&~x[4])|(x[2]&x[3]&x[4]); 6 | endmodule 7 | -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.4 Karnaugh Map to Circuit/3.1.4.4 kmap4.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input a, 3 | input b, 4 | input c, 5 | input d, 6 | output out ); 7 | assign out = a^b^c^d; 8 | endmodule 9 | -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.3 Arithmetic Circuits/3.1.3.2 full adder.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input a, b, cin, 3 | output cout, sum ); 4 | assign cout = a&b | b&cin | a&cin; 5 | assign sum = a^b^cin; 6 | endmodule 7 | -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.4 Karnaugh Map to Circuit/3.1.4.3 kmap3.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input a, 3 | input b, 4 | input c, 5 | input d, 6 | output out ); 7 | assign out = a | ~b&c; 8 | endmodule 9 | -------------------------------------------------------------------------------- /4 Verification Reading Simulations/4.1 Finding bugs in code/4.1.2 NAND.v: -------------------------------------------------------------------------------- 1 | module top_module (input a, input b, input c, output out);// 2 | wire and_out; 3 | andgate inst1(and_out, a, b, c, 1, 1 ); 4 | assign out = ~and_out; 5 | endmodule 6 | -------------------------------------------------------------------------------- /2 Verilog Language/2.1 Basics/2.1.2 four_wires.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input a,b,c, 3 | output w,x,y,z ); 4 | 5 | assign w = a; 6 | assign x = b; 7 | assign y = b; 8 | assign z = c; 9 | 10 | endmodule 11 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.1 Latches and Flip-Flops/3.2.1.10 DFF_gate.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input in, 4 | output out); 5 | always @(posedge clk) begin 6 | out <= out^in; 7 | end 8 | endmodule 9 | -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.4 Karnaugh Map to Circuit/3.1.4.2 kmap2.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input a, 3 | input b, 4 | input c, 5 | input d, 6 | output out ); 7 | assign out = ~d&~a | ~c&~b | c&d&(a|b); 8 | endmodule 9 | -------------------------------------------------------------------------------- /2 Verilog Language/2.3 Modules Hierachy/2.3.2 module_pos.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input a, 3 | input b, 4 | input c, 5 | input d, 6 | output out1, 7 | output out2 8 | ); 9 | mod_a aa(out1,out2,a,b,c,d); 10 | endmodule 11 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.1 Latches and Flip-Flops/3.2.1.7 D Latch.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input d, 3 | input ena, 4 | output q); 5 | 6 | always @ (*) begin 7 | if (ena) q<=d; 8 | end 9 | 10 | endmodule 11 | -------------------------------------------------------------------------------- /2 Verilog Language/2.5 More Verilog Features/2.5.3 gate100.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input [99:0] in, 3 | output out_and, 4 | output out_or, 5 | output out_xor 6 | ); 7 | assign {out_and,out_or,out_xor} = {&in,|in,^in}; 8 | 9 | endmodule 10 | -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.4 Karnaugh Map to Circuit/3.1.4.8 kmap with a multiplexer.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input c, 3 | input d, 4 | output [3:0] mux_in 5 | ); 6 | assign mux_in = (c&d)?4'b1001:(c)?4'b0101:(d)?4'b0001:4'b0100; 7 | endmodule 8 | -------------------------------------------------------------------------------- /2 Verilog Language/2.5 More Verilog Features/2.5.1 conditional.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input [7:0] a, b, c, d, 3 | output [7:0] min);// 4 | 5 | wire [7:0] min1 = (a0 instead of the more natural 15->0 8 | q <= 0; 9 | else 10 | q <= q+1; 11 | 12 | endmodule 13 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.2 Counters/3.2.2.3 decade counter2.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input reset, 4 | output [3:0] q); 5 | always @(posedge clk) begin 6 | if (reset || q == 4'd10) 7 | q <= 4'd1; 8 | else 9 | q <= q + 1; 10 | 11 | end 12 | 13 | endmodule 14 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.1 Latches and Flip-Flops/3.2.1.16 Dual Edge Detector.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input [7:0] in, 4 | output [7:0] anyedge 5 | ); 6 | reg [7:0]dlast; 7 | 8 | always @ (posedge clk) begin 9 | dlast <= in; 10 | anyedge <= dlast ^ in; 11 | end 12 | 13 | endmodule 14 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.5 Finite State Machines/3.2.5.27 Q6b FSM next-state logic.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input [3:1] y, 3 | input w, 4 | output Y2); 5 | 6 | parameter E=3'b100, F=3'b101, D=3'b011, C=3'b010, B=3'b001; 7 | 8 | assign Y2 = (y==B) || (y==F) || (y==C && w) || (y==E && w); 9 | 10 | 11 | endmodule 12 | -------------------------------------------------------------------------------- /2 Verilog Language/2.2 Vectors/2.2.5 four-input_gates.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input [3:0] in, 3 | output out_and, 4 | output out_or, 5 | output out_xor 6 | ); 7 | assign out_and = in[0] & in[1] & in[2] & in[3] ; 8 | assign out_or = in[0] | in[1] | in[2] | in[3]; 9 | assign out_xor = in[0] ^ in[1] ^ in[2] ^ in[3]; 10 | endmodule 11 | -------------------------------------------------------------------------------- /4 Verification Reading Simulations/4.2 Build a circuit from a simulation waveform/4.2.1 Combinational Circuit 1.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input a, 3 | input b, 4 | output q 5 | ); 6 | 7 | // This is a combinational circuit with one gate. The truth table 8 | // can be found by looking at the simulation waveforms. 9 | assign q = a & b; 10 | 11 | endmodule 12 | -------------------------------------------------------------------------------- /2 Verilog Language/2.2 Vectors/2.2.1 vectors.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input wire [2:0] vec, 3 | output wire [2:0] outv, 4 | output wire o2, 5 | output wire o1, 6 | output wire o0 ); // Module body starts after module declaration 7 | assign outv = vec; 8 | assign o2 = vec[2]; 9 | assign o1 = vec[1]; 10 | assign o0 = vec[0]; 11 | endmodule 12 | -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.1 Basic Gates/3.1.1.15 3-bit population count.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input [2:0] in, 3 | output [1:0] out ); 4 | integer i,count; 5 | always @ * begin 6 | count = 0; 7 | for (i=0; i<3;i=i+1) begin 8 | if (in[i]==1'b1) count=count+1; 9 | end 10 | out = count; 11 | end 12 | 13 | endmodule -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.1 Latches and Flip-Flops/3.2.1.11 MUX and DFF.v: -------------------------------------------------------------------------------- 1 | 2 | module top_module ( 3 | input clk, 4 | input L, 5 | input r_in, 6 | input q_in, 7 | output reg Q); 8 | 9 | always @ (posedge clk) begin 10 | case (L) 11 | 1'b0 : Q <= q_in; 12 | 1'b1 : Q <= r_in; 13 | endcase 14 | end 15 | 16 | endmodule -------------------------------------------------------------------------------- /2 Verilog Language/2.2 Vectors/2.2.9 more_replication.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input a, b, c, d, e, 3 | output [24:0] out );// 4 | wire [4:0] k = {a,b,c,d,e}; 5 | assign out[24:20] = ~ {5{a}} ^ k; 6 | assign out[19:15] = ~ {5{b}} ^ k; 7 | assign out[14:10] = ~ {5{c}} ^ k; 8 | assign out[9:5] = ~ {5{d}} ^ k; 9 | assign out[4:0] = ~ {5{e}} ^ k; 10 | endmodule 11 | -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.3 Arithmetic Circuits/3.1.3.5 signed addition overflow.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input [7:0] a, 3 | input [7:0] b, 4 | output [7:0] s, 5 | output overflow 6 | ); // 7 | wire [8:0] sum; 8 | assign sum = a+b; 9 | assign s = sum[7:0]; 10 | assign overflow = a[7]&&b[7]&&(~s[7]) || (~a[7])&&(~b[7])&&(s[7]); 11 | endmodule 12 | -------------------------------------------------------------------------------- /3 Circuit/3.3 Building Larger Circuits/3.3.1 counter with period 1000.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input reset, 4 | output reg [9:0] q); 5 | 6 | always @(posedge clk) begin 7 | if (reset) 8 | q <= 0; 9 | else if ( q == 10'd999) 10 | q <= 0; 11 | else 12 | q <= q + 1; 13 | end 14 | 15 | endmodule 16 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.1 Latches and Flip-Flops/3.2.1.13 DFFs and Gates.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input x, 4 | output z 5 | ); 6 | reg q,q1,q2; 7 | always @(posedge clk) 8 | begin 9 | 10 | q<= q^x; 11 | q1<= ~q1 && x; 12 | q2<= ~q2 || x; 13 | 14 | end 15 | assign z=~(q | q1 | q2); 16 | endmodule -------------------------------------------------------------------------------- /5 Verification Writing Testbenches/5.2 Testbench1.v: -------------------------------------------------------------------------------- 1 | module top_module ( output reg A, output reg B );// 2 | 3 | // generate input patterns here 4 | initial begin 5 | A = 1'b0; 6 | B = 1'b0; 7 | #10; 8 | A = 1'b1; 9 | #5 10 | B = 1'b1; 11 | #5 12 | A = 1'b0; 13 | #20 14 | B = 1'b0; 15 | end 16 | 17 | endmodule 18 | -------------------------------------------------------------------------------- /2 Verilog Language/2.1 Basics/2.1.7 declaring_wires.v: -------------------------------------------------------------------------------- 1 | `default_nettype none 2 | module top_module( 3 | input a, 4 | input b, 5 | input c, 6 | input d, 7 | output out, 8 | output out_n ); 9 | 10 | wire in1,in2; 11 | assign in1 = a & b; 12 | assign in2 = c & d; 13 | assign out = in1 | in2; 14 | assign out_n = ~(in1 | in2); 15 | 16 | 17 | endmodule 18 | -------------------------------------------------------------------------------- /2 Verilog Language/2.3 Modules Hierachy/2.3.9 module_addsub.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input [31:0] a, 3 | input [31:0] b, 4 | input sub, 5 | output [31:0] sum 6 | ); 7 | wire cout,cout2; 8 | wire [31:0] b_in; 9 | assign b_in = b^{32{sub}}; 10 | add16 a1(a[15:0],b_in[15:0],sub,sum[15:0],cout); 11 | add16 a2(a[31:16],b_in[31:16],cout,sum[31:16],cout2); 12 | 13 | endmodule 14 | -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.1 Basic Gates/3.1.1.14 thermostat.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input too_cold, 3 | input too_hot, 4 | input mode, 5 | input fan_on, 6 | output heater, 7 | output aircon, 8 | output fan 9 | ); 10 | assign fan = fan_on | heater | aircon; 11 | assign heater = mode & too_cold; 12 | assign aircon = ~mode & too_hot; 13 | 14 | endmodule 15 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.4 More Circuits/3.2.4.2 Rule 110.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input clk, 3 | input load, 4 | input [511:0] data, 5 | output [511:0] q 6 | ); 7 | 8 | always @(posedge clk) begin 9 | if(load) 10 | q <= data; 11 | else 12 | q <= q^{q[510:0],1'b0} | q & ~{1'b0,q[511:1]} ; 13 | end 14 | 15 | endmodule 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HDLBits_Solution 2 | Included are comprehensive solutions to the problem sets provided on [HDLBits](https://hdlbits.01xz.net/wiki/Main_Page) as a practice purpose. 3 | 4 | There are multiple solutions to these problems so I collect both my thoughts and ideas written by the author. 5 | 6 | This practice is finished during the summer 2020. 7 | Hope it helps you. Feel free to share it and comments are welcomed! 8 | 9 | -------------------------------------------------------------------------------- /4 Verification Reading Simulations/4.2 Build a circuit from a simulation waveform/4.2.10 Sequential circuit 7.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input a, 4 | input b, 5 | output q, 6 | output state ); 7 | 8 | always @(posedge clk) begin 9 | if (a == b) 10 | state <= a; 11 | end 12 | 13 | assign q = a^b^state; 14 | 15 | 16 | endmodule 17 | -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.1 Basic Gates/3.1.1.17 even longer vectors.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input [99:0] in, 3 | output [98:0] out_both, 4 | output [99:1] out_any, 5 | output [99:0] out_different ); 6 | 7 | assign out_any = in[99:1] | in[98:0]; 8 | 9 | assign out_both = in[98:0] & in[99:1]; 10 | 11 | assign out_different = in ^ {in[0], in[99:1]}; 12 | 13 | endmodule 14 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.3 Shift Registers/3.2.3.7 Shift Register 1.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input resetn, // synchronous reset 4 | input in, 5 | output out); 6 | reg [3:0] Q; 7 | assign out = Q[0]; 8 | always@(posedge clk) begin 9 | if (~resetn) 10 | Q <= 4'd0; 11 | else 12 | Q <= {in,Q[3:1]}; 13 | end 14 | 15 | endmodule 16 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.1 Latches and Flip-Flops/3.2.1.15 Edge Detector.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input clk, 3 | input [7:0] in, 4 | output reg [7:0] pedge); 5 | 6 | reg [7:0] d_last; 7 | 8 | always @(posedge clk) begin 9 | d_last <= in; // Remember the state of the previous cycle 10 | pedge <= in & ~d_last; // A positive edge occurred if input was 0 and is now 1. 11 | end 12 | 13 | endmodule 14 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.1 Latches and Flip-Flops/3.2.1.14 Truth Table.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input j, 4 | input k, 5 | output Q); 6 | always @ (posedge clk) begin 7 | case ({j,k}) 8 | 2'b00: Q <= Q; 9 | 2'b01: Q <= 1'b0; 10 | 2'b10: Q <= 1'b1; 11 | 2'b11: Q <= ~Q; 12 | endcase 13 | end 14 | 15 | endmodule 16 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.3 Shift Registers/3.2.3.5 3-bit LFSR.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input [2:0] SW, // R 3 | input [1:0] KEY, // L and clk 4 | output reg [2:0] LEDR); // Q 5 | 6 | wire clk = KEY[0]; 7 | wire L = KEY[1]; 8 | wire [2:0] d = (L)?SW:{LEDR[1]^LEDR[2],LEDR[0],LEDR[2]}; 9 | 10 | always @(posedge clk)begin 11 | LEDR <= d; 12 | end 13 | 14 | endmodule 15 | -------------------------------------------------------------------------------- /4 Verification Reading Simulations/4.2 Build a circuit from a simulation waveform/4.2.8 Sequential circuit 7.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clock, 3 | input a, 4 | output p, 5 | output q ); 6 | 7 | always@(*)begin 8 | if(clock)begin 9 | p = a; 10 | end 11 | end 12 | 13 | always@(negedge clock)begin 14 | q <= p; 15 | end 16 | 17 | 18 | endmodule 19 | -------------------------------------------------------------------------------- /2 Verilog Language/2.4 Procedures/2.4.2 alwaysblock2.v: -------------------------------------------------------------------------------- 1 | // synthesis verilog_input_version verilog_2001 2 | module top_module( 3 | input clk, 4 | input a, 5 | input b, 6 | output wire out_assign, 7 | output reg out_always_comb, 8 | output reg out_always_ff ); 9 | assign out_assign = a^b; 10 | always @(*) out_always_comb = a^b; 11 | always @(posedge clk) out_always_ff <= a^b; 12 | 13 | endmodule 14 | -------------------------------------------------------------------------------- /4 Verification Reading Simulations/4.1 Finding bugs in code/4.1.3 MUX2.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input [1:0] sel, 3 | input [7:0] a, 4 | input [7:0] b, 5 | input [7:0] c, 6 | input [7:0] d, 7 | output [7:0] out ); // 8 | 9 | wire [7:0] out1, out2; 10 | mux2 mux0 ( sel[0], a, b, out1 ); 11 | mux2 mux1 ( sel[0], c, d, out2 ); 12 | mux2 mux2 ( sel[1], out1, out2, out ); 13 | 14 | endmodule 15 | -------------------------------------------------------------------------------- /5 Verification Writing Testbenches/5.1 Clock.v: -------------------------------------------------------------------------------- 1 | module top_module ( ); 2 | reg clk; 3 | dut clock(clk); 4 | 5 | initial begin 6 | clk = 1'b0; 7 | forever 8 | #5 9 | clk = ~clk; 10 | end 11 | 12 | /* 13 | initial begin 14 | clk = 1'b0; 15 | end 16 | 17 | always begin 18 | #5 19 | clk = ~clk; 20 | end 21 | */ 22 | 23 | endmodule 24 | -------------------------------------------------------------------------------- /3 Circuit/3.3 Building Larger Circuits/3.3.2 4-bit SR and down counter.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input shift_ena, 4 | input count_ena, 5 | input data, 6 | output [3:0] q); 7 | 8 | always@(posedge clk)begin 9 | if(shift_ena)begin 10 | q <= {q[2:0], data}; 11 | end 12 | else if(count_ena)begin 13 | q <= q - 1'b1; 14 | end 15 | end 16 | 17 | endmodule 18 | -------------------------------------------------------------------------------- /4 Verification Reading Simulations/4.2 Build a circuit from a simulation waveform/4.2.9 Sequential circuit 7.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input a, 4 | output [3:0] q ); 5 | always @(posedge clk) begin 6 | if (a) 7 | q <= 4'd4; 8 | else begin 9 | if (q == 4'd6) 10 | q <= 0; 11 | else 12 | q <= q + 1; 13 | end 14 | end 15 | 16 | endmodule 17 | -------------------------------------------------------------------------------- /2 Verilog Language/2.2 Vectors/2.2.4 bitwise_operators.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input [2:0] a, 3 | input [2:0] b, 4 | output [2:0] out_or_bitwise, 5 | output out_or_logical, 6 | output [5:0] out_not 7 | ); 8 | 9 | assign out_or_bitwise = a | b; 10 | assign out_or_logical = a || b; 11 | 12 | assign out_not[2:0] = ~a; // Part-select on left side is o. 13 | assign out_not[5:3] = ~b; //Assigning to [5:3] does not conflict with [2:0] 14 | 15 | endmodule -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.1 Latches and Flip-Flops/3.2.1.1 DFF.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input clk, 3 | input d, 4 | output reg q); 5 | 6 | // Use non-blocking assignment for edge-triggered always blocks 7 | always @(posedge clk) 8 | q <= d; 9 | 10 | // Undefined simulation behaviour can occur if there is more than one edge-triggered 11 | // always block and blocking assignment is used. Which always block is simulated first? 12 | 13 | endmodule 14 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.2 Counters/3.2.2.5 slow decade counter.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input reset, 4 | input enable, 5 | output [3:0] Q, 6 | output c_enable, 7 | output c_load, 8 | output [3:0] c_d 9 | ); // 10 | assign c_enable = enable; 11 | assign c_load = reset | (Q == 4'd12 & enable == 1); 12 | assign c_d = 4'd1; 13 | count4 the_counter (clk, c_enable, c_load, c_d, Q); 14 | 15 | endmodule 16 | -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.3 Arithmetic Circuits/3.1.3.7 4-digit BCD adder.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input [15:0] a, b, 3 | input cin, 4 | output cout, 5 | output [15:0] sum ); 6 | 7 | wire c1,c2,c3; 8 | bcd_fadd b1(a[3:0],b[3:0],cin,c1,sum[3:0]); 9 | bcd_fadd b2(a[7:4],b[7:4],c1,c2,sum[7:4]); 10 | bcd_fadd b3(a[11:8],b[11:8],c2,c3,sum[11:8]); 11 | bcd_fadd b4(a[15:12],b[15:12],c3,cout,sum[15:12]); 12 | 13 | endmodule 14 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.1 Latches and Flip-Flops/3.2.1.12 MUX and DFF n.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input w, R, E, L, 4 | output Q 5 | ); 6 | wire [1:0] con = {E,L}; 7 | always @(posedge clk) begin 8 | case(con) 9 | 2'b00: Q <= Q; 10 | 2'b01: Q <= R; 11 | 2'b11: Q <= R; 12 | 2'b10: Q <= w; 13 | endcase 14 | 15 | end 16 | 17 | 18 | endmodule 19 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.2 Counters/3.2.2.4 counter 1-to-12.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input slowena, 4 | input reset, 5 | output [3:0] q); 6 | always @(posedge clk) begin 7 | if (slowena) begin 8 | if (q == 4'd9) 9 | q<=0; 10 | else 11 | q<=q+1; 12 | end 13 | if(reset) begin 14 | q<=0; 15 | end 16 | end 17 | 18 | 19 | endmodule 20 | -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.1 Basic Gates/3.1.1.9 two-bit equality.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input [1:0] A, 3 | input [1:0] B, 4 | output z); 5 | // assign z = (A[0] == B[0]) && (A[1] == B[1]); 6 | assign z = (A[1:0]==B[1:0]); // Comparisons produce a 1 or 0 result. 7 | 8 | // Another option is to use a 16-entry truth table ( {A,B} is 4 bits, with 16 combinations ). 9 | // There are 4 rows with a 1 result. 0000, 0101, 1010, and 1111. 10 | 11 | endmodule 12 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.2 Counters/3.2.2.1 4-bit BC.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input clk, 3 | input reset, 4 | output reg [3:0] q); 5 | 6 | always @(posedge clk) 7 | if (reset) 8 | q <= 0; 9 | else 10 | q <= q+1; // Because q is 4 bits, it rolls over from 15 -> 0. 11 | // If you want a counter that counts a range different from 0 to (2^n)-1, 12 | // then you need to add another rule to reset q to 0 when roll-over should occur. 13 | 14 | endmodule 15 | -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.1 Basic Gates/3.1.1.13 ring or vibrate.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input ring, 3 | input vibrate_mode, 4 | output ringer, 5 | output motor 6 | ); 7 | 8 | // When should ringer be on? When (phone is ringing) and (phone is not in vibrate mode) 9 | assign ringer = ring & ~vibrate_mode; 10 | 11 | // When should motor be on? When (phone is ringing) and (phone is in vibrate mode) 12 | assign motor = ring & vibrate_mode; 13 | 14 | endmodule 15 | -------------------------------------------------------------------------------- /2 Verilog Language/2.3 Modules Hierachy/2.3.7 module_fadd.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input [31:0] a, 3 | input [31:0] b, 4 | output [31:0] sum 5 | );// 6 | wire con1, con2; 7 | add16 adder_1(a[15:0], b[15:0], 0, sum[15:0], con1); 8 | add16 adder_2(a[31:16], b[31:16], con1, sum[31:16], con2); 9 | endmodule 10 | 11 | module add1 ( input a, input b, input cin, output sum, output cout ); 12 | assign sum = a^b^cin; 13 | assign cout = a&b | a&cin | b&cin; 14 | endmodule 15 | -------------------------------------------------------------------------------- /4 Verification Reading Simulations/4.1 Finding bugs in code/4.1.4 Add_SUB.v: -------------------------------------------------------------------------------- 1 | // synthesis verilog_input_version verilog_2001 2 | module top_module ( 3 | input do_sub, 4 | input [7:0] a, 5 | input [7:0] b, 6 | output reg [7:0] out, 7 | output reg result_is_zero 8 | );// 9 | 10 | always @(*) begin 11 | case (do_sub) 12 | 0: out = a+b; 13 | 1: out = a-b; 14 | endcase 15 | 16 | result_is_zero = (out == 0); 17 | end 18 | 19 | endmodule 20 | -------------------------------------------------------------------------------- /2 Verilog Language/2.5 More Verilog Features/2.5.6 adder100i.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input [99:0] a, b, 3 | input cin, 4 | output [99:0] cout, 5 | output [99:0] sum ); 6 | 7 | integer i; 8 | always @(*) begin 9 | sum[0] = a[0] ^ b[0] ^ cin; 10 | cout[0] = a[0] & b[0] | cin & (a[0]|b[0]); 11 | for (i = 1; i<100; i++) begin 12 | sum[i] = a[i] ^ b[i] ^ cout[i-1]; 13 | cout[i] = a[i] & b[i] | cout[i-1] & (a[i]|b[i]); 14 | end 15 | end 16 | 17 | endmodule 18 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.1 Latches and Flip-Flops/3.2.1.6 DFF_byteEnable.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input resetn, 4 | input [1:0] byteena, 5 | input [15:0] d, 6 | output [15:0] q 7 | ); 8 | always @(posedge clk) begin 9 | case(byteena) 10 | 2'b01: q <= (~resetn)? 16'd0:{q[15:8],d[7:0]}; 11 | 2'b10: q <= (~resetn)? 16'd0:{d[15:8],q[7:0]}; 12 | 2'b11: q <= (~resetn)? 16'd0:{d[15:8],d[7:0]}; 13 | endcase 14 | 15 | end 16 | endmodule 17 | -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.3 Arithmetic Circuits/3.1.3.3 3-bit binary adder.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input [2:0] a, b, 3 | input cin, 4 | output [2:0] cout, 5 | output [2:0] sum ); 6 | 7 | FA FA1(a[0],b[0],cin,cout[0],sum[0]); 8 | FA FA2(a[1],b[1],cout[0],cout[1],sum[1]); 9 | FA FA3(a[2],b[2],cout[1],cout[2],sum[2]); 10 | 11 | endmodule 12 | 13 | module FA( 14 | input a, b, cin, 15 | output cout, sum ); 16 | 17 | assign cout = a&b | b&cin | a&cin; 18 | assign sum = a^b^cin; 19 | endmodule -------------------------------------------------------------------------------- /4 Verification Reading Simulations/4.2 Build a circuit from a simulation waveform/4.2.5 Combinational Circuit 5.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input [3:0] a, 3 | input [3:0] b, 4 | input [3:0] c, 5 | input [3:0] d, 6 | input [3:0] e, 7 | output [3:0] q ); 8 | 9 | always @(*) begin 10 | case(c) 11 | 4'd0: q = b; 12 | 4'd1: q = e; 13 | 4'd2: q = a; 14 | 4'd3: q = d; 15 | default: q = 4'hf; 16 | endcase 17 | end 18 | 19 | endmodule 20 | -------------------------------------------------------------------------------- /4 Verification Reading Simulations/4.2 Build a circuit from a simulation waveform/4.2.6 Combinational Circuit 6.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input [2:0] a, 3 | output [15:0] q ); 4 | always@(*)begin 5 | case(a) 6 | 0: q = 16'h1232; 7 | 1: q = 16'haee0; 8 | 2: q = 16'h27d4; 9 | 3: q = 16'h5a0e; 10 | 4: q = 16'h2066; 11 | 5: q = 16'h64ce; 12 | 6: q = 16'hc526; 13 | 7: q = 16'h2f19; 14 | endcase 15 | end 16 | 17 | endmodule 18 | -------------------------------------------------------------------------------- /2 Verilog Language/2.4 Procedures/2.4.3 always_if.v: -------------------------------------------------------------------------------- 1 | // synthesis verilog_input_version verilog_2001 2 | module top_module( 3 | input a, 4 | input b, 5 | input sel_b1, 6 | input sel_b2, 7 | output wire out_assign, 8 | output reg out_always ); 9 | 10 | assign out_assign = (sel_b1&sel_b2)?b:a; 11 | 12 | always@(*) begin 13 | if (sel_b1&sel_b2) begin 14 | out_always = b; 15 | end 16 | else begin 17 | out_always = a; 18 | end 19 | end 20 | endmodule 21 | -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.1 Basic Gates/3.1.1.5 more logic gates.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input a, b, 3 | output out_and, 4 | output out_or, 5 | output out_xor, 6 | output out_nand, 7 | output out_nor, 8 | output out_xnor, 9 | output out_anotb 10 | ); 11 | assign out_and = a&b; 12 | assign out_or = a|b; 13 | assign out_xor = a^b; 14 | assign out_nand = ~out_and; 15 | assign out_nor = ~out_or; 16 | assign out_xnor = ~out_xor; 17 | assign out_anotb = a&~b; 18 | 19 | endmodule 20 | -------------------------------------------------------------------------------- /2 Verilog Language/2.4 Procedures/2.4.4 always_if2.v: -------------------------------------------------------------------------------- 1 | // synthesis verilog_input_version verilog_2001 2 | module top_module ( 3 | input cpu_overheated, 4 | output reg shut_off_computer, 5 | input arrived, 6 | input gas_tank_empty, 7 | output reg keep_driving ); // 8 | 9 | always @(*) begin 10 | if (cpu_overheated) 11 | shut_off_computer = 1; 12 | end 13 | 14 | always @(*) begin 15 | if (~arrived) 16 | keep_driving = ~gas_tank_empty; 17 | end 18 | 19 | endmodule 20 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.2 Counters/3.2.2.6 counter 1000.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input reset, 4 | output OneHertz, 5 | output [2:0] c_enable 6 | ); // 7 | 8 | wire [3:0] q0, q1, q2; 9 | assign OneHertz = {q0 == 4'd9 && q1 == 4'd9 && q2 == 4'd9}; 10 | assign c_enable = {q1 == 4'd9 && q0 == 4'd9, q0 == 4'd9, 1'b1}; 11 | 12 | 13 | bcdcount counter0 (clk, reset, c_enable[0], q0); 14 | bcdcount counter1 (clk, reset, c_enable[1], q1); 15 | bcdcount counter2 (clk, reset, c_enable[2], q2); 16 | 17 | endmodule -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.1 Basic Gates/3.1.1.8 truth tables.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input x3, 3 | input x2, 4 | input x1, 5 | output f 6 | ); 7 | // This truth table has four minterms. 8 | assign f = ( ~x3 & x2 & ~x1 ) | 9 | ( ~x3 & x2 & x1 ) | 10 | ( x3 & ~x2 & x1 ) | 11 | ( x3 & x2 & x1 ) ; 12 | 13 | // It can be simplified, by boolean algebra or Karnaugh maps. 14 | // assign f = (~x3 & x2) | (x3 & x1); 15 | 16 | // You may then notice that this is actually a 2-to-1 mux, selected by x3: 17 | // assign f = x3 ? x1 : x2; 18 | 19 | endmodule 20 | -------------------------------------------------------------------------------- /2 Verilog Language/2.4 Procedures/2.4.8 always_nolatches.v: -------------------------------------------------------------------------------- 1 | // synthesis verilog_input_version verilog_2001 2 | module top_module ( 3 | input [15:0] scancode, 4 | output reg left, 5 | output reg down, 6 | output reg right, 7 | output reg up ); 8 | 9 | always @(*) begin 10 | up = 1'b0; down = 1'b0; left = 1'b0; right = 1'b0; 11 | case (scancode) 12 | 16'he06b: left = 1'b1; 13 | 16'he072: down = 1'b1; 14 | 16'he074: right = 1'b1; 15 | 16'he075: up = 1'b1; 16 | endcase 17 | end 18 | 19 | 20 | endmodule 21 | -------------------------------------------------------------------------------- /2 Verilog Language/2.5 More Verilog Features/2.5.7 bcdadd100.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input [399:0] a, b, 3 | input cin, 4 | output cout, 5 | output [399:0] sum ); 6 | 7 | wire[99:0] cout_wires; 8 | genvar i; 9 | 10 | generate 11 | bcd_fadd(a[3:0], b[3:0], cin, cout_wires[0],sum[3:0]); 12 | for (i=4; i<400; i=i+4) begin: bcd_adder_instances 13 | bcd_fadd bcd_adder(a[i+3:i], b[i+3:i], cout_wires[i/4-1],cout_wires[i/4],sum[i+3:i]); 14 | end 15 | endgenerate 16 | 17 | assign cout = cout_wires[99]; 18 | 19 | endmodule 20 | -------------------------------------------------------------------------------- /2 Verilog Language/2.3 Modules Hierachy/2.3.5 module_shift8.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input [7:0] d, 4 | input [1:0] sel, 5 | output reg [7:0] q 6 | ); 7 | 8 | wire [7:0] o1, o2, o3; // output of each my_dff8 9 | 10 | // Instantiate three my_dff8s 11 | my_dff8 d1 ( clk, d, o1 ); 12 | my_dff8 d2 ( clk, o1, o2 ); 13 | my_dff8 d3 ( clk, o2, o3 ); 14 | 15 | // This is one way to make a 4-to-1 multiplexer 16 | always @(*) // Combinational always block 17 | case(sel) 18 | 2'h0: q = d; 19 | 2'h1: q = o1; 20 | 2'h2: q = o2; 21 | 2'h3: q = o3; 22 | endcase 23 | 24 | endmodule -------------------------------------------------------------------------------- /2 Verilog Language/2.3 Modules Hierachy/2.3.8 module_cseladd.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input [31:0] a, 3 | input [31:0] b, 4 | output [31:0] sum 5 | ); 6 | wire cout1,cout2a,cout2b; 7 | wire [15:0] sum2a,sum2b; 8 | add16 add1(a[15:0],b[15:0],0,sum[15:0],cout1); 9 | add16 add2a(a[31:16],b[31:16],0,sum2a,cout2a); 10 | add16 add2b(a[31:16],b[31:16],1,sum2b,cout2b); 11 | 12 | always @(*) begin 13 | case (cout1) 14 | 0: sum[31:16] = sum2a; 15 | 1: sum[31:16] = sum2b; 16 | 17 | endcase 18 | 19 | end 20 | 21 | endmodule -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.3 Arithmetic Circuits/3.1.3.4 adder.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input [3:0] x, 3 | input [3:0] y, 4 | output [4:0] sum 5 | ); 6 | 7 | // This circuit is a 4-bit ripple-carry adder with carry-out. 8 | assign sum = x+y; // Verilog addition automatically produces the carry-out bit. 9 | 10 | // Verilog quirk: Even though the value of (x+y) includes the carry-out, (x+y) is still considered to be a 4-bit number (The max width of the two operands). 11 | // This is correct: 12 | // assign sum = (x+y); 13 | // But this is incorrect: 14 | // assign sum = {x+y}; // Concatenation operator: This discards the carry-out 15 | endmodule 16 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.1 Latches and Flip-Flops/3.2.1.17 Dual-edge triggered FF.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input reset, 4 | input [31:0] in, 5 | output [31:0] out 6 | ); 7 | reg [31:0] d_last; 8 | wire [31:0] state; 9 | assign state = d_last & ~in; 10 | always@( posedge clk) begin 11 | d_last <= in; 12 | if (reset) begin 13 | out <= '0; 14 | end 15 | else begin 16 | for (int i = 0; i<32; i++) begin 17 | if(state[i] == 1'b1) 18 | out[i] <= 1'b1; 19 | 20 | end 21 | end 22 | 23 | end 24 | 25 | endmodule 26 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.3 Shift Registers/3.2.3.1 4-bit SR.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input clk, 3 | input areset, 4 | input load, 5 | input ena, 6 | input [3:0] data, 7 | output reg [3:0] q); 8 | 9 | // Asynchronous reset: Notice the sensitivity list. 10 | // The shift register has four modes: 11 | // reset 12 | // load 13 | // enable shift 14 | // idle -- preserve q (i.e., DFFs) 15 | always @(posedge clk, posedge areset) begin 16 | if (areset) // reset 17 | q <= 0; 18 | else if (load) // load 19 | q <= data; 20 | else if (ena) // shift is enabled 21 | q <= q[3:1]; // Use vector part select to express a shift. 22 | end 23 | 24 | endmodule 25 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.5 Finite State Machines/3.2.5.23 Q5b serial 2s complementer Mealy.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input areset, 4 | input x, 5 | output z 6 | ); 7 | parameter a=0,b=1; 8 | reg state,next; 9 | 10 | always@(*) begin 11 | case(state) 12 | a: next = (x)? b:a; 13 | b: next = b; 14 | endcase 15 | end 16 | 17 | always@(posedge clk or posedge areset) begin 18 | if (areset) 19 | state <= a; 20 | else 21 | state <= next; 22 | end 23 | 24 | assign z = (state == a) & x || (state == b) & ~x; 25 | 26 | endmodule 27 | -------------------------------------------------------------------------------- /5 Verification Writing Testbenches/5.5 TFF.v: -------------------------------------------------------------------------------- 1 | module top_module (); 2 | reg clk; 3 | reg reset; 4 | reg t; 5 | wire q; 6 | 7 | initial begin 8 | clk = 0; 9 | reset = 0; 10 | t = 0; 11 | #3; 12 | reset = 1'b1; 13 | #10; 14 | reset = 1'b0; 15 | end 16 | 17 | always begin 18 | #5 19 | clk = ~clk; 20 | end 21 | 22 | always@(posedge clk)begin 23 | if(reset)begin 24 | t <= 1'b0; 25 | end 26 | else begin 27 | t <= 1'b1; 28 | end 29 | end 30 | 31 | 32 | tff u_tff(clk,reset,t,q); 33 | 34 | endmodule 35 | -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.1 Basic Gates/3.1.1.12 combine circuits A and B.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input x, 3 | input y, 4 | output z); 5 | 6 | wire o1, o2, o3, o4; 7 | 8 | A ia1 (x, y, o1); 9 | B ib1 (x, y, o2); 10 | A ia2 (x, y, o3); 11 | B ib2 (x, y, o4); 12 | 13 | assign z = (o1 | o2) ^ (o3 & o4); 14 | 15 | // Or you could simplify the circuit including the sub-modules: 16 | // assign z = x|~y; 17 | 18 | endmodule 19 | 20 | module A ( 21 | input x, 22 | input y, 23 | output z); 24 | 25 | assign z = (x^y) & x; 26 | 27 | endmodule 28 | 29 | module B ( 30 | input x, 31 | input y, 32 | output z); 33 | 34 | assign z = ~(x^y); 35 | 36 | endmodule 37 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.3 Shift Registers/3.2.3.2 left_right rotator.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input clk, 3 | input load, 4 | input [1:0] ena, 5 | input [99:0] data, 6 | output reg [99:0] q); 7 | 8 | // This rotator has 4 modes: 9 | // load 10 | // rotate left 11 | // rotate right 12 | // do nothing 13 | // I used vector part-select and concatenation to express a rotation. 14 | // Edge-sensitive always block: Use non-blocking assignments. 15 | always @(posedge clk) begin 16 | if (load) // Load 17 | q <= data; 18 | else if (ena == 2'h1) // Rotate right 19 | q <= {q[0], q[99:1]}; 20 | else if (ena == 2'h2) // Rotate left 21 | q <= {q[98:0], q[99]}; 22 | end 23 | endmodule 24 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.5 Finite State Machines/3.2.5.22 Q5a serial 2s complementer Moore.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input areset, 4 | input x, 5 | output z 6 | ); 7 | 8 | parameter a=0, b=1, c=2; 9 | reg[1:0] state,next; 10 | 11 | always@(*) begin 12 | case(state) 13 | a: next = (x)? b : a; 14 | b: next = (x)? c : b; 15 | c: next = (x)? c : b; 16 | endcase 17 | end 18 | 19 | always@(posedge clk or posedge areset) begin 20 | if (areset) 21 | state <= a; 22 | else 23 | state <= next; 24 | end 25 | 26 | assign z = (state == b); 27 | 28 | 29 | endmodule 30 | -------------------------------------------------------------------------------- /4 Verification Reading Simulations/4.1 Finding bugs in code/4.1.1 MUX1.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input sel, 3 | input [7:0] a, 4 | input [7:0] b, 5 | output reg [7:0] out 6 | ); 7 | 8 | // 1. A mux coded as (~sel & a) | (sel & b) does not work for vectors. 9 | // This is because these are bitwise operators, and sel is only a 1 bit wide quantity, 10 | // which leaves the upper bits of a and b zeroed. It is possible to code it using 11 | // the replication operator, but this is somewhat difficult to read: 12 | // ( {8{~sel}} & a ) | ( {8{sel}} & b ) 13 | 14 | // 2. The simulation waveform shows that when sel = 1, a should be selected. This 15 | // is flipped in the suggested code. 16 | 17 | assign out = sel ? a : b; 18 | 19 | endmodule 20 | -------------------------------------------------------------------------------- /2 Verilog Language/2.3 Modules Hierachy/2.3.1 module.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input a, 3 | input b, 4 | output out 5 | ); 6 | 7 | // Create an instance of "mod_a" named "inst1", and connect ports by name: 8 | mod_a inst1 ( 9 | .in1(a), // Port"in1"connects to wire "a" 10 | .in2(b), // Port "in2" connects to wire "b" 11 | .out(out) // Port "out" connects to wire "out" 12 | // (Note: mod_a's port "out" is not related to top_module's wire "out". 13 | // It is simply coincidence that they have the same name) 14 | ); 15 | 16 | /* 17 | // Create an instance of "mod_a" named "inst2", and connect ports by position: 18 | mod_a inst2 ( a, b, out ); // The three wires are connected to ports in1, in2, and out, respectively. 19 | */ 20 | 21 | endmodule -------------------------------------------------------------------------------- /2 Verilog Language/2.4 Procedures/2.4.5 always_case.v: -------------------------------------------------------------------------------- 1 | 2 | // synthesis verilog_input_version verilog_2001 3 | module top_module ( 4 | input [2:0] sel, 5 | input [3:0] data0, 6 | input [3:0] data1, 7 | input [3:0] data2, 8 | input [3:0] data3, 9 | input [3:0] data4, 10 | input [3:0] data5, 11 | output reg [3:0] out );// 12 | 13 | always@(*) begin // This is a combinational circuit 14 | case(sel) 15 | 3'b000: out = data0; 16 | 3'b001: out = data1; 17 | 3'b010: out = data2; 18 | 3'b011: out = data3; 19 | 3'b100: out = data4; 20 | 3'b101: out = data5; 21 | default: out = 4'b0000; 22 | endcase 23 | end 24 | 25 | endmodule 26 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.3 Shift Registers/3.2.3.3 left_right_arithmetic_shift.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input clk, 3 | input load, 4 | input ena, 5 | input [1:0] amount, 6 | input [63:0] data, 7 | output reg [63:0] q); 8 | 9 | always @(posedge clk) begin 10 | if(load) 11 | q <= data; 12 | else if (ena) 13 | begin 14 | case(amount) 15 | 2'b00: q <= {q[62:0],1'b0}; 16 | 2'b01: q <= {q[55:0],8'b0}; 17 | 2'b10: q <= {q[63],q[63:1]}; 18 | 2'b11: q <= {{8{q[63]}},q[63-:56]}; 19 | endcase 20 | 21 | end 22 | 23 | end 24 | 25 | endmodule 26 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.3 Shift Registers/3.2.3.6 32-bit LFSR.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input clk, 3 | input reset, // Active-high synchronous reset to 32'h1 4 | output [31:0] q 5 | ); 6 | reg [31:0] q_next; 7 | 8 | always @(*) begin 9 | q_next = q[31:1]; // Shift all the bits. This is incorrect for q_next[4] and q_next[2] 10 | q_next[31] = q[0]; // Give q_next[4] and q_next[2] their correct assignments 11 | q_next[21] = q[22] ^ q[0]; 12 | q_next[1] = q[2] ^ q[0]; 13 | q_next[0] = q[1] ^ q[0]; 14 | end 15 | 16 | always @(posedge clk) begin 17 | if (reset) 18 | q <= 32'h1; 19 | else 20 | q <= q_next; 21 | end 22 | 23 | 24 | endmodule 25 | -------------------------------------------------------------------------------- /5 Verification Writing Testbenches/5.4 Testbench2.v: -------------------------------------------------------------------------------- 1 | module top_module(); 2 | reg clk; 3 | reg in; 4 | reg[2:0] s; 5 | wire out; 6 | 7 | initial begin 8 | clk = 1'b0; 9 | forever 10 | #5 11 | clk = ~clk; 12 | end 13 | 14 | initial begin 15 | in = 1'b0; 16 | s = 3'd2; 17 | #10; 18 | in = 1'b0; 19 | s = 3'd6; 20 | #10; 21 | in = 1'b1; 22 | s = 3'd2; 23 | #10; 24 | in = 1'b0; 25 | s = 3'd7; 26 | #10; 27 | in = 1'b1; 28 | s = 3'd0; 29 | #30; 30 | in = 1'b0; 31 | s = 3'd0; 32 | end 33 | 34 | q7 u_q7(clk, in, s, out); 35 | 36 | 37 | endmodule 38 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.5 Finite State Machines/3.2.5.26 Q3c FSM logic.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input [2:0] y, 4 | input x, 5 | output Y0, 6 | output z 7 | ); 8 | 9 | reg[2:0] state,next; 10 | parameter A=3'b000,B=3'b001,C=3'b010,D=3'b011,E=3'b100; 11 | 12 | always@(*) begin 13 | case(y) 14 | A: next = (~x)? A : B; 15 | B: next = (~x)? B : E; 16 | C: next = (~x)? C : B; 17 | D: next = (~x)? B : C; 18 | E: next = (~x)? D : E; 19 | endcase 20 | end 21 | 22 | always@(posedge clk) begin 23 | state <= next; 24 | end 25 | 26 | assign z = (y == D) || (y == E); 27 | assign Y0 = next[0]; 28 | endmodule 29 | -------------------------------------------------------------------------------- /3 Circuit/3.3 Building Larger Circuits/3.3.4 FSM Enable SR.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input reset, // Synchronous reset 4 | output shift_ena); 5 | 6 | parameter A=0,B=1,C=2,D=3,E=4; 7 | reg[2:0] state, next; 8 | 9 | always@(*) begin 10 | case(state) 11 | A: next = (reset)? B:A; 12 | B: next = (reset)? B:C; 13 | C: next = (reset)? B:D; 14 | D: next = (reset)? B:E; 15 | E: next = (reset)? B:A; 16 | endcase 17 | end 18 | always@(posedge clk) begin 19 | if (reset) 20 | state <= B; 21 | else 22 | state <= next; 23 | end 24 | 25 | assign shift_ena = (state != A); 26 | 27 | endmodule 28 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.4 More Circuits/3.2.4.1 Rule 90.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input clk, 3 | input load, 4 | input [511:0] data, 5 | output reg [511:0] q); 6 | 7 | always @(posedge clk) begin 8 | if (load) 9 | q <= data; // Load the DFFs with a value. 10 | else begin 11 | // At each clock, the DFF storing each bit position becomes the XOR of its left neighbour 12 | // and its right neighbour. Since the operation is the same for every 13 | // bit position, it can be written as a single operation on vectors. 14 | // The shifts are accomplished using part select and concatenation operators. 15 | 16 | // left right 17 | // neighbour neighbour 18 | q <= {1'b0,q[511:1]} ^ {q[510:0], 1'b0} ; 19 | end 20 | end 21 | endmodule -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.5 Finite State Machines/3.2.5.25 Q3b FSM5.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input reset, // Synchronous reset 4 | input x, 5 | output z 6 | ); 7 | 8 | parameter A=0,B=1,C=2,D=3,E=4; 9 | reg[2:0] state, next; 10 | 11 | always@(*) begin 12 | case(state) 13 | A: next = (~x)? A : B; 14 | B: next = (~x)? B : E; 15 | C: next = (~x)? C : B; 16 | D: next = (~x)? B : C; 17 | E: next = (~x)? D : E; 18 | endcase 19 | end 20 | 21 | always@(posedge clk) begin 22 | if (reset) 23 | state <= A; 24 | else 25 | state <= next; 26 | end 27 | 28 | assign z = (state == D) || (state == E); 29 | 30 | 31 | endmodule 32 | -------------------------------------------------------------------------------- /4 Verification Reading Simulations/4.1 Finding bugs in code/4.1.5 Case statement.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input [7:0] code, 3 | output reg [3:0] out, 4 | output reg valid 5 | ); 6 | 7 | // A combinational always block. 8 | always @(*) begin 9 | out = 0; // To avoid latches, give the outputs a default assignment 10 | valid = 1; // then override them in the case statement. This is less 11 | // code than assigning a value to every variable for every case. 12 | case (code) 13 | 8'h45: out = 0; 14 | 8'h16: out = 1; 15 | 8'h1e: out = 2; 16 | 8'h26: out = 3; // 8'd26 is 8'h1a 17 | 8'h25: out = 4; 18 | 8'h2e: out = 5; 19 | 8'h36: out = 6; 20 | 8'h3d: out = 7; 21 | 8'h3e: out = 8; 22 | 8'h46: out = 9; 23 | default: valid = 0; 24 | endcase 25 | end 26 | 27 | endmodule 28 | -------------------------------------------------------------------------------- /3 Circuit/3.3 Building Larger Circuits/3.3.3 FSM 1101 sequence recognizer.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input reset, // Synchronous reset 4 | input data, 5 | output start_shifting); 6 | 7 | parameter A=0,B=1,C=2,D=3,E=4; 8 | reg[2:0] state,next; 9 | 10 | always@(*) begin 11 | case(state) 12 | A: next = (data)? B:A; 13 | B: next = (data)? C:A; 14 | C: next = (data)? C:D; 15 | D: next = (data)? E:A; 16 | E: next = (reset)? A:E; 17 | endcase 18 | end 19 | 20 | always@(posedge clk) begin 21 | if (reset) 22 | state <= A; 23 | else 24 | state <= next; 25 | end 26 | 27 | assign start_shifting = (state == E); 28 | 29 | 30 | endmodule 31 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.5 Finite State Machines/3.2.5.29 Q6 FSM7.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input reset, // synchronous reset 4 | input w, 5 | output z); 6 | 7 | parameter A=0,B=1,C=2,D=3,E=4,F=5; 8 | reg[3:0] state,next; 9 | 10 | always@(*) begin 11 | case(state) 12 | A: next = (w)? A:B; 13 | B: next = (w)? D:C; 14 | C: next = (w)? D:E; 15 | D: next = (w)? A:F; 16 | E: next = (w)? D:E; 17 | F: next = (w)? D:C; 18 | endcase 19 | end 20 | 21 | always@(posedge clk) begin 22 | if(reset) 23 | state <= A; 24 | else 25 | state <= next; 26 | end 27 | 28 | assign z = (state==E) || (state == F); 29 | 30 | endmodule 31 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.5 Finite State Machines/3.2.5.30 Q2a FSM8.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input reset, // synchronous reset 4 | input w, 5 | output z); 6 | 7 | parameter A=0,B=1,C=2,D=3,E=4,F=5; 8 | reg[3:0] state,next; 9 | 10 | always@(*) begin 11 | case(state) 12 | A: next = (~w)? A:B; 13 | B: next = (~w)? D:C; 14 | C: next = (~w)? D:E; 15 | D: next = (~w)? A:F; 16 | E: next = (~w)? D:E; 17 | F: next = (~w)? D:C; 18 | endcase 19 | end 20 | 21 | always@(posedge clk) begin 22 | if(reset) 23 | state <= A; 24 | else 25 | state <= next; 26 | end 27 | 28 | assign z = (state==E) || (state == F); 29 | 30 | endmodule 31 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.5 Finite State Machines/3.2.5.3 FSM2_ar.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input clk, 3 | input areset, // Asynchronous reset to OFF 4 | input j, 5 | input k, 6 | output out); // 7 | 8 | parameter OFF=0, ON=1; 9 | reg state, next_state; 10 | 11 | always @(*) begin 12 | // State transition logic 13 | case(state) 14 | OFF: next_state = (j)? ON:OFF; 15 | ON: next_state = (k)? OFF:ON; 16 | endcase 17 | end 18 | 19 | always @(posedge clk, posedge areset) begin 20 | // State flip-flops with asynchronous reset 21 | if (areset) 22 | state <= OFF; 23 | else 24 | state <= next_state; 25 | end 26 | 27 | // Output logic 28 | assign out = (state == ON); 29 | 30 | endmodule 31 | -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.2 Multiplexers/3.1.2.4 256-to-1 multiplexer.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input [1023:0] in, 3 | input [7:0] sel, 4 | output [3:0] out 5 | ); 6 | 7 | // We can't part-select multiple bits without an error, but we can select one bit at a time, 8 | // four times, then concatenate them together. 9 | assign out = {in[sel*4+3], in[sel*4+2], in[sel*4+1], in[sel*4+0]}; 10 | 11 | // Alternatively, "indexed vector part select" works better, but has an unfamiliar syntax: 12 | // assign out = in[sel*4 +: 4]; // Select starting at index "sel*4", then select a total width of 4 bits with increasing (+:) index number. 13 | // assign out = in[sel*4+3 -: 4]; // Select starting at index "sel*4+3", then select a total width of 4 bits with decreasing (-:) index number. 14 | // Note: The width (4 in this case) must be constant. 15 | 16 | endmodule 17 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.3 Shift Registers/3.2.3.8 Shift Register 2.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input [3:0] SW, 3 | input [3:0] KEY, 4 | output [3:0] LEDR 5 | ); // 6 | 7 | wire [3:0] w_input = {KEY[3],LEDR[3],LEDR[2],LEDR[1]}; 8 | generate 9 | genvar i; 10 | for(i=0;i<4;i=i+1) begin: muxdff 11 | MUXDFF ( 12 | .clk(KEY[0]), 13 | .w(w_input[i]), 14 | .R(SW[i]), 15 | .E(KEY[1]), 16 | .L(KEY[2]), 17 | .Q(LEDR[i]) 18 | ); 19 | end 20 | endgenerate 21 | endmodule 22 | 23 | 24 | module MUXDFF ( 25 | input clk, 26 | input w, R, E, L, 27 | output Q 28 | ); 29 | reg Q_r; 30 | wire d_in = (L)?R:(E)?w:Q_r; 31 | always@(posedge clk)begin 32 | Q_r <= d_in; 33 | end 34 | assign Q = Q_r; 35 | endmodule -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.3 Shift Registers/3.2.3.9 3-input LUT.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input enable, 4 | input S, 5 | 6 | input A, B, C, 7 | output reg Z 8 | ); 9 | 10 | reg [7:0] q; 11 | 12 | // The final circuit is a shift register attached to a 8-to-1 mux. 13 | 14 | 15 | 16 | // Create a 8-to-1 mux that chooses one of the bits of q based on the three-bit number {A,B,C}: 17 | // There are many other ways you could write a 8-to-1 mux 18 | // (e.g., combinational always block -> case statement with 8 cases). 19 | assign Z = q[ {A, B, C} ]; 20 | 21 | 22 | 23 | // Edge-triggered always block: This is a standard shift register (named q) with enable. 24 | // When enabled, shift to the left by 1 (discarding q[7] and and shifting in S). 25 | always @(posedge clk) begin 26 | if (enable) 27 | q <= {q[6:0], S}; 28 | end 29 | 30 | 31 | 32 | endmodule 33 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.5 Finite State Machines/3.2.5.14 One-hot FSM.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input in, 3 | input [9:0] state, 4 | output [9:0] next_state, 5 | output out1, 6 | output out2); 7 | 8 | always@ (*) begin 9 | next_state[0] = (state[0] | state[1] | state[2] | state[3] | state[4] | state[7] | state[8] | state[9]) & ~in; 10 | next_state[1] = (state[8] | state[9] | state[0]) & in; 11 | next_state[2] = state[1] & in; 12 | next_state[3] = state[2] & in; 13 | next_state[4] = state[3] & in; 14 | next_state[5] = state[4] & in; 15 | next_state[6] = state[5] & in; 16 | next_state[7] = (state[6] | state[7]) & in; 17 | next_state[8] = state[5] & ~in; 18 | next_state[9] = state[6] & ~in; 19 | end 20 | 21 | assign out1 = state[8] || state[9]; 22 | assign out2 = state[7] || state[9]; 23 | 24 | 25 | endmodule 26 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.2 Counters/3.2.2.7 4-digit decimal counter.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input reset, // Synchronous active-high reset 4 | output [3:1] ena, 5 | output reg [15:0] q); 6 | 7 | assign ena = {q[11:8] == 4'd9 && q[7:4] == 4'd9 && q[3:0] == 4'd9, q[7:4] == 4'd9 && q[3:0] == 4'd9, q[3:0] == 4'd9}; 8 | 9 | BCD bcd0(clk,reset,1,q[3:0]); 10 | BCD bcd1(clk,reset,ena[1],q[7:4]); 11 | BCD bcd2(clk,reset,ena[2],q[11:8]); 12 | BCD bcd3(clk,reset,ena[3],q[15:12]); 13 | 14 | endmodule 15 | 16 | 17 | module BCD ( 18 | input clk, 19 | input reset, 20 | input ena, 21 | output reg [3:0] Q 22 | ); 23 | always@(posedge clk) begin 24 | if (reset) 25 | Q <= 0; 26 | else if (ena) 27 | begin 28 | if (Q == 4'd9) 29 | Q <= 4'd0; 30 | else 31 | Q <= Q + 1'd1; 32 | end 33 | end 34 | 35 | endmodule 36 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.1 Latches and Flip-Flops/3.2.1.5 DFF_areset.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input clk, 3 | input [7:0] d, 4 | input areset, 5 | output reg [7:0] q); 6 | 7 | // The only difference in code compared to synchronous reset is in the sensitivity list. 8 | always @(posedge clk, posedge areset) 9 | if (areset) 10 | q <= 0; 11 | else 12 | q <= d; 13 | 14 | 15 | // In Verilog, the sensitivity list looks strange. The FF's reset is sensitive to the 16 | // *level* of areset, so why does using "posedge areset" work? 17 | // To see why it works, consider the truth table for all events that change the input 18 | // signals, assuming clk and areset do not switch at precisely the same time: 19 | 20 | // clk areset output 21 | // x 0->1 q <= 0; (because areset = 1) 22 | // x 1->0 no change (always block not triggered) 23 | // 0->1 0 q <= d; (not resetting) 24 | // 0->1 1 q <= 0; (still resetting, q was 0 before too) 25 | // 1->0 x no change (always block not triggered) 26 | 27 | endmodule 28 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.5 Finite State Machines/3.2.5.32 Q2a FSM9.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input resetn, // active-low synchronous reset 4 | input [3:1] r, // request 5 | output [3:1] g // grant 6 | ); 7 | wire r1,r2,r3,g1,g2,g3; 8 | assign {r3,r2,r1} = r; 9 | assign g = {g3,g2,g1}; 10 | 11 | parameter A=0,B=1,C=2,D=3; 12 | reg[1:0] state, next; 13 | 14 | always@(*) begin 15 | case(state) 16 | A: next = (r1)? B : (r2) ? C : (r3)? D : A; 17 | B: next = (r1)? B : A; 18 | C: next = (r2)? C : A; 19 | D: next = (r3)? D : A; 20 | default next = A; 21 | endcase 22 | end 23 | 24 | always@(posedge clk) begin 25 | if (!resetn) 26 | state <= A; 27 | else 28 | state <= next; 29 | end 30 | 31 | assign g1 = (state == B); 32 | assign g2 = (state == C); 33 | assign g3 = (state == D); 34 | 35 | 36 | 37 | 38 | endmodule 39 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.5 Finite State Machines/3.2.5.17 serial receiver.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input clk, 3 | input in, 4 | input reset, // Synchronous reset 5 | output done 6 | ); 7 | parameter i=0, r=1, d=2, e=3; 8 | reg[1:0] state, next; 9 | int cnt; 10 | 11 | always @(*) begin 12 | case(state) 13 | i: next = (~in)? r: i; 14 | r: next = (cnt == 9 && in)? d : (cnt==9 && ~in)? e : r; // 9 for end bit 15 | d: next = (~in)? r: i; 16 | e: next = (in)? i : e; 17 | endcase 18 | end 19 | 20 | always @(posedge clk) begin 21 | if (reset) begin 22 | state <= i; 23 | cnt = 0; // 0 for start bit 24 | end 25 | else begin 26 | state <= next; 27 | if (next == r) 28 | cnt = cnt + 1; 29 | if (next == e || next == d) 30 | cnt = 0; 31 | end 32 | end 33 | 34 | assign done = (state == d); 35 | 36 | endmodule 37 | -------------------------------------------------------------------------------- /2 Verilog Language/2.4 Procedures/2.4.7 always_casez.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input [7:0] in, 3 | output reg [2:0] pos ); 4 | 5 | // casez treats bits that have the value z as don't-care in the comparison. 6 | 7 | //Notice how there are certain inputs (e.g., 4'b1111) that will match more than one case item. 8 | //The first match is chosen (so 4'b1111 matches the first item, out = 0, but not any of the later ones). 9 | 10 | //There is also a similar casex that treats both x and z as don't-care. I don't see much purpose to using it over casez. 11 | //The digit ? is a synonym for z. so 2'bz0 is the same as 2'b?0 12 | 13 | always @(*) begin 14 | casez (in[7:0]) 15 | 8'bzzzzzzz1: pos = 0; 16 | 8'bzzzzzz1z: pos = 1; 17 | 8'bzzzzz1zz: pos = 2; 18 | 8'bzzzz1zzz: pos = 3; 19 | 8'bzzz1zzzz: pos = 4; 20 | 8'bzz1zzzzz: pos = 5; 21 | 8'bz1zzzzzz: pos = 6; 22 | 8'b1zzzzzzz: pos = 7; 23 | default: pos = 0; 24 | endcase 25 | end 26 | endmodule -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.5 Finite State Machines/3.2.5.15 PS2 packet parser.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input clk, 3 | input [7:0] in, 4 | input reset, // Synchronous reset 5 | output done); // 6 | 7 | parameter init=0, read=1, d = 2; 8 | reg[1:0] state, next; 9 | int cnt; 10 | // State transition logic (combinational) 11 | always @(*) begin 12 | case(state) 13 | init: next = (in[3])? read : init; 14 | read: next = (cnt == 3)? d : read; 15 | d: next = (in[3])? read : init; 16 | endcase 17 | end 18 | 19 | // State flip-flops (sequential) 20 | always@ (posedge clk) begin 21 | if (reset) begin 22 | state <= init; 23 | cnt = 1; 24 | end 25 | else begin 26 | state <= next; 27 | if (next == read) 28 | cnt = cnt + 1; 29 | if (next == d) 30 | cnt = 1; 31 | end 32 | end 33 | 34 | 35 | // Output logic 36 | assign done = (state == d); 37 | 38 | endmodule 39 | -------------------------------------------------------------------------------- /3 Circuit/3.3 Building Larger Circuits/3.3.7 One-hot logic equations.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input d, 3 | input done_counting, 4 | input ack, 5 | input [9:0] state, // 10-bit one-hot current state 6 | output B3_next, 7 | output S_next, 8 | output S1_next, 9 | output Count_next, 10 | output Wait_next, 11 | output done, 12 | output counting, 13 | output shift_ena 14 | ); // 15 | 16 | // You may use these parameters to access state bits using e.g., state[B2] instead of state[6]. 17 | parameter S=0, S1=1, S11=2, S110=3, B0=4, B1=5, B2=6, B3=7, Count=8, Wait=9; 18 | 19 | assign B3_next = state[B2]; 20 | assign S_next = ~d & state[S] | ~d & state[S1] | ~d & state[S110] | ack & state[Wait]; 21 | assign S1_next = d & state[S]; 22 | assign Count_next = state[B3] | ~done_counting & state[Count]; 23 | assign Wait_next = done_counting & state[Count] | ~ack & state[Wait]; 24 | assign done = state[Wait]; 25 | assign counting = state[Count]; 26 | assign shift_ena = state[B0] | state[B1] | state[B2] |state[B3]; 27 | 28 | endmodule 29 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.5 Finite State Machines/3.2.5.16 PS2 packet parser and datapath.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input clk, 3 | input [7:0] in, 4 | input reset, // Synchronous reset 5 | output [23:0] out_bytes, 6 | output done); // 7 | 8 | parameter B1=0, B2=1, B3=2, d=3; 9 | reg[1:0] state, next; 10 | 11 | // FSM from fsm_ps2 12 | always @(*) begin 13 | case(state) 14 | B1: next = (in[3])? B2:B1; 15 | B2: next = B3; 16 | B3: next = d; 17 | d: next = (in[3])? B2:B1; 18 | endcase 19 | end 20 | 21 | always @(posedge clk) begin 22 | if (reset) 23 | state <= B1; 24 | else begin 25 | state <= next; 26 | case(next) 27 | B2: out_bytes[23:16] = in; 28 | B3: out_bytes[15:8] = in; 29 | d: out_bytes[7:0] = in; 30 | endcase 31 | end 32 | 33 | end 34 | 35 | // New: Datapath to store incoming bytes. 36 | assign done = (state == d); 37 | endmodule 38 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.5 Finite State Machines/3.2.5.11 Lemmings 2.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input clk, 3 | input areset, // Freshly brainwashed Lemmings walk left. 4 | input bump_left, 5 | input bump_right, 6 | input ground, 7 | output walk_left, 8 | output walk_right, 9 | output aaah ); 10 | 11 | parameter L=0,R=1,LF=2,RF=3; 12 | reg [1:0] state, next_state; 13 | 14 | always @(*) begin 15 | case(state) 16 | L: next_state = (~ground)? LF : (bump_left)? R : L; 17 | R: next_state = (~ground)? RF : (bump_right)? L : R; 18 | LF: next_state = (ground)? L : LF; 19 | RF: next_state = (ground)? R : RF; 20 | endcase 21 | end 22 | 23 | always @(posedge clk or posedge areset) begin 24 | if (areset) 25 | state <= L; 26 | else 27 | state <= next_state; 28 | 29 | end 30 | 31 | 32 | assign walk_left = (state == L); 33 | assign walk_right = (state == R); 34 | assign aaah = (state == LF) || (state == RF); 35 | 36 | 37 | endmodule 38 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.5 Finite State Machines/3.2.5.2 FSM1_r.v: -------------------------------------------------------------------------------- 1 | // Note the Verilog-1995 module declaration syntax here: 2 | module top_module(clk, reset, in, out); 3 | input clk; 4 | input reset; // Synchronous reset to state B 5 | input in; 6 | output out;// 7 | reg out; 8 | 9 | // Fill in state name declarations 10 | parameter A=0, B=1; 11 | 12 | reg present_state, next_state; 13 | 14 | always @(posedge clk) begin 15 | if (reset) begin 16 | // Fill in reset logic 17 | present_state <= B; 18 | out = 1; 19 | end else begin 20 | case (present_state) 21 | // Fill in state transition logic 22 | A: next_state = (in)? A : B; 23 | B: next_state = (in)? B : A; 24 | endcase 25 | 26 | // State flip-flops 27 | present_state = next_state; 28 | 29 | case (present_state) 30 | // Fill in output logic 31 | A: out = 0; 32 | B: out = 1; 33 | endcase 34 | end 35 | end 36 | 37 | endmodule 38 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.5 Finite State Machines/3.2.5.20 sequence recognition.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input clk, 3 | input reset, // Synchronous reset 4 | input in, 5 | output disc, 6 | output flag, 7 | output err); 8 | 9 | parameter i=0, one=1, two=2, thr=3, four=4, fiv=5, six=6, er=7, ds=8, flg=9; 10 | reg[3:0] state, next; 11 | 12 | always@(*) begin 13 | case(state) 14 | i: next = (in)? one:i; 15 | one: next = (in)? two:i; 16 | two: next = (in)? thr:i; 17 | thr: next = (in)? four:i; 18 | four: next = (in)? fiv:i; 19 | fiv: next = (in)? six:ds; 20 | six: next = (in)? er:flg; 21 | er: next = (in)? er:i; 22 | ds: next = (in)? one:i; 23 | flg: next = (in)? one:i; 24 | endcase 25 | end 26 | 27 | always@(posedge clk) begin 28 | if(reset) 29 | state <= i; 30 | else 31 | state <= next; 32 | end 33 | 34 | assign disc = (state == ds); 35 | assign flag = (state == flg); 36 | assign err = (state == er); 37 | 38 | 39 | 40 | endmodule 41 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.5 Finite State Machines/3.2.5.18 serial receiver and datapath.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input clk, 3 | input in, 4 | input reset, // Synchronous reset 5 | output [7:0] out_byte, 6 | output done 7 | ); // 8 | 9 | parameter i=0, r=1, d=2, e=3; 10 | reg[1:0] state, next; 11 | int cnt; 12 | 13 | always @(*) begin 14 | case(state) 15 | i: next = (~in)? r: i; 16 | r: next = (cnt == 9 && in)? d : (cnt==9 && ~in)? e : r; // 9 for end bit 17 | d: next = (~in)? r: i; 18 | e: next = (in)? i : e; 19 | endcase 20 | end 21 | 22 | always @(posedge clk) begin 23 | if (reset) begin 24 | state <= i; 25 | cnt = 0; // 0 for start bit 26 | end 27 | else begin 28 | state <= next; 29 | if (next == r) begin 30 | cnt = cnt + 1; 31 | if (cnt > 1) 32 | out_byte[cnt - 2] = in; 33 | end 34 | if (next == e || next == d) begin 35 | cnt = 0; 36 | end 37 | end 38 | end 39 | 40 | assign done = (state == d); 41 | 42 | endmodule 43 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.1 Latches and Flip-Flops/3.2.1.17 Edge Capture.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input clk, 3 | input d, 4 | output q); 5 | 6 | reg p, n; 7 | 8 | // A positive-edge triggered flip-flop 9 | always @(posedge clk) 10 | p <= d ^ n; 11 | 12 | // A negative-edge triggered flip-flop 13 | always @(negedge clk) 14 | n <= d ^ p; 15 | 16 | // Why does this work? 17 | // After posedge clk, p changes to d^n. Thus q = (p^n) = (d^n^n) = d. 18 | // After negedge clk, n changes to p^n. Thus q = (p^n) = (p^p^n) = d. 19 | // At each (positive or negative) clock edge, p and n FFs alternately 20 | // load a value that will cancel out the other and cause the new value of d to remain. 21 | assign q = p ^ n; 22 | 23 | 24 | // Can't synthesize this. 25 | /*always @(posedge clk, negedge clk) begin 26 | q <= d; 27 | end*/ 28 | 29 | 30 | endmodule 31 | 32 | /* 33 | module top_module ( 34 | input clk, 35 | input d, 36 | output q 37 | ); 38 | reg q1,q2; 39 | assign q = clk? q1:q2; 40 | always@(posedge clk) begin 41 | q1 <= d; 42 | end 43 | always@(negedge clk) begin 44 | q2 <= d; 45 | end 46 | 47 | endmodule 48 | */ -------------------------------------------------------------------------------- /3 Circuit/3.3 Building Larger Circuits/3.3.5 FSM Complete FSM.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input reset, // Synchronous reset 4 | input data, 5 | output shift_ena, 6 | output counting, 7 | input done_counting, 8 | output done, 9 | input ack ); 10 | 11 | parameter S=0,S1=1,S11=2,S110=3, B0=4, B1=5, B2=6, B3=7, cnt=8, hold=9; 12 | reg[3:0] state, next; 13 | 14 | always@ (*) begin 15 | case(state) 16 | S: next = (data)? S1 : S; 17 | S1: next = (data)? S11: S; 18 | S11: next = (~data)? S110:S11; 19 | S110: next = (data)? B0 : S; 20 | B0: next = B1; 21 | B1: next = B2; 22 | B2: next = B3; 23 | B3: next = cnt; 24 | cnt: next = (done_counting)? hold:cnt; 25 | hold: next = (ack)? S:hold; 26 | endcase 27 | end 28 | 29 | always@(posedge clk) begin 30 | if (reset) 31 | state <= S; 32 | else 33 | state <= next; 34 | end 35 | 36 | assign shift_ena = (state == B0) || (state == B1) || (state == B2) || (state == B3); 37 | assign counting = (state == cnt); 38 | assign done = (state == hold); 39 | 40 | 41 | endmodule 42 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.5 Finite State Machines/3.2.5.12 Lemmings 3.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input clk, 3 | input areset, // Freshly brainwashed Lemmings walk left. 4 | input bump_left, 5 | input bump_right, 6 | input ground, 7 | input dig, 8 | output walk_left, 9 | output walk_right, 10 | output aaah, 11 | output digging ); 12 | 13 | parameter L=0,R=1,LF=2,RF=3, LD=4, RD =5; 14 | reg [2:0] state, next_state; 15 | 16 | always @(*) begin 17 | case(state) 18 | L: next_state = (~ground)? LF : (dig)? LD : (bump_left)? R : L; 19 | R: next_state = (~ground)? RF : (dig)? RD : (bump_right)? L : R; 20 | LF: next_state = (ground)? L : LF; 21 | RF: next_state = (ground)? R : RF; 22 | LD: next_state = (ground)? LD : LF; 23 | RD: next_state = (ground)? RD : RF; 24 | endcase 25 | end 26 | 27 | always @ (posedge clk or posedge areset) begin 28 | if(areset) 29 | state <= L; 30 | else 31 | state <= next_state; 32 | end 33 | 34 | assign aaah = (state == LF) || (state == RF); 35 | assign walk_left = (state == L); 36 | assign walk_right = (state == R); 37 | assign digging = (state == LD) || (state == RD); 38 | 39 | 40 | 41 | endmodule 42 | -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.1 Basic Gates/3.1.1.16 gates and vectors.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input [3:0] in, 3 | output [2:0] out_both, 4 | output [3:1] out_any, 5 | output [3:0] out_different ); 6 | 7 | assign out_both = {in[3]&in[2],in[2]&in[1],in[1]&in[0]}; 8 | assign out_any = {in[3]|in[2],in[2]|in[1],in[1]|in[0]}; 9 | assign out_different = {in[0]^in[3],in[3]^in[2],in[2]^in[1],in[1]^in[0]}; 10 | 11 | /* 12 | // Use bitwise operators and part-select to do the entire calculation in one line of code 13 | // in[3:1] is this vector: in[3] in[2] in[1] 14 | // in[2:0] is this vector: in[2] in[1] in[0] 15 | // Bitwise-OR produces a 3 bit vector. | | | 16 | // Assign this 3-bit result to out_any[3:1]: o_a[3] o_a[2] o_a[1] 17 | 18 | // Thus, each output bit is the OR of the input bit and its neighbour to the right: 19 | // e.g., out_any[1] = in[1] | in[0]; 20 | // Notice how this works even for long vectors. 21 | assign out_any = in[3:1] | in[2:0]; 22 | 23 | assign out_both = in[2:0] & in[3:1]; 24 | 25 | // XOR 'in' with a vector that is 'in' rotated to the right by 1 position: {in[0], in[3:1]} 26 | // The rotation is accomplished by using part selects[] and the concatenation operator{}. 27 | assign out_different = in ^ {in[0], in[3:1]}; 28 | */ 29 | 30 | 31 | endmodule 32 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.5 Finite State Machines/3.2.5.24 Q3a FSM4.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input reset, // Synchronous reset 4 | input s, 5 | input w, 6 | output z 7 | ); 8 | parameter a=0, b=1; 9 | reg state, next; 10 | 11 | always@(*) begin 12 | case(state) 13 | a: next = (s)? b : a; 14 | b: next = b; 15 | endcase 16 | end 17 | 18 | always@(posedge clk) begin 19 | if (reset) 20 | state <= a; 21 | else 22 | state <= next; 23 | end 24 | 25 | int clk_cnt; 26 | reg[1:0] cnt; 27 | 28 | always@(posedge clk) begin 29 | if (reset || state == a) begin 30 | clk_cnt = 0; 31 | cnt = 0; 32 | end 33 | 34 | else begin 35 | if (state == b) begin 36 | if (clk_cnt < 3) 37 | clk_cnt = clk_cnt + 1; 38 | else begin // clk_cnt = 3, reset cnt first 39 | clk_cnt = 1; 40 | cnt = 0; 41 | end 42 | end 43 | if(next == b) begin 44 | cnt = cnt + w; 45 | end 46 | end 47 | end 48 | 49 | assign z = (cnt == 2'd2) && (clk_cnt == 3); 50 | 51 | endmodule 52 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.5 Finite State Machines/3.2.5.19 serial receiver with parity checking.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input clk, 3 | input in, 4 | input reset, // Synchronous reset 5 | output [7:0] out_byte, 6 | output done 7 | ); // 8 | 9 | parameter i=0, r=1, d=2, e=3, dp=4; 10 | reg[2:0] state, next; 11 | reg odd; 12 | 13 | parity p_check(clk,~(state == r), in, odd); 14 | 15 | int cnt; 16 | 17 | always @(*) begin 18 | case(state) 19 | i: next = (~in)? r: i; 20 | r: next = (cnt == 9 && in == ~odd)? dp : (cnt==9 && ~(in==~odd))? e : r; // 9 for parity bit 21 | dp: next = (in)? d:e; // parity check finish 22 | d: next = (~in)? r: i; 23 | e: next = (in)? i : e; 24 | endcase 25 | end 26 | 27 | always @(posedge clk) begin 28 | if (reset) begin 29 | state <= i; 30 | cnt = 0; // 0 for start bit 31 | end 32 | else begin 33 | state <= next; 34 | if (next == r) begin 35 | cnt = cnt + 1; 36 | if (cnt > 1) 37 | out_byte[cnt - 2] = in; 38 | end 39 | if (next == e || next == d) begin 40 | cnt = 0; 41 | end 42 | end 43 | end 44 | 45 | assign done = (state == d); 46 | 47 | endmodule 48 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.5 Finite State Machines/3.2.5.10 Lemmings 1.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input areset, 4 | input bump_left, 5 | input bump_right, 6 | output walk_left, 7 | output walk_right 8 | ); 9 | 10 | // Give state names and assignments. I'm lazy, so I like to use decimal numbers. 11 | // It doesn't really matter what assignment is used, as long as they're unique. 12 | parameter WL=0, WR=1; 13 | reg state; 14 | reg next; 15 | 16 | 17 | // Combinational always block for state transition logic. Given the current state and inputs, 18 | // what should be next state be? 19 | // Combinational always block: Use blocking assignments. 20 | always@(*) begin 21 | case (state) 22 | WL: next = bump_left ? WR : WL; 23 | WR: next = bump_right ? WL : WR; 24 | endcase 25 | end 26 | 27 | 28 | // Combinational always block for state transition logic. Given the current state and inputs, 29 | // what should be next state be? 30 | // Combinational always block: Use blocking assignments. 31 | always @(posedge clk, posedge areset) begin 32 | if (areset) state <= WL; 33 | else state <= next; 34 | end 35 | 36 | 37 | // Combinational output logic. In this problem, an assign statement are the simplest. 38 | // In more complex circuits, a combinational always block may be more suitable. 39 | assign walk_left = (state==WL); 40 | assign walk_right = (state==WR); 41 | 42 | 43 | endmodule 44 | -------------------------------------------------------------------------------- /3 Circuit/3.1 Combinational Logic/3.1.2 Multiplexers/3.1.2.3 9-to-1 multiplexer.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input [15:0] a, b, c, d, e, f, g, h, i, 3 | input [3:0] sel, 4 | output [15:0] out ); 5 | always @(*) begin 6 | case (sel) 7 | 4'd0: out = a; 8 | 4'd1: out = b; 9 | 4'd2: out = c; 10 | 4'd3: out = d; 11 | 4'd4: out = e; 12 | 4'd5: out = f; 13 | 4'd6: out = g; 14 | 4'd7: out = h; 15 | 4'd8: out = i; 16 | default: out = {16{1'b1}}; 17 | endcase 18 | end 19 | endmodule 20 | 21 | /* 22 | module top_module ( 23 | input [15:0] a, 24 | input [15:0] b, 25 | input [15:0] c, 26 | input [15:0] d, 27 | input [15:0] e, 28 | input [15:0] f, 29 | input [15:0] g, 30 | input [15:0] h, 31 | input [15:0] i, 32 | input [3:0] sel, 33 | output logic [15:0] out 34 | ); 35 | 36 | // Case statements can only be used inside procedural blocks (always block) 37 | // This is a combinational circuit, so use a combinational always @(*) block. 38 | always @(*) begin 39 | out = '1; // '1 is a special literal syntax for a number with all bits set to 1. 40 | // '0, 'x, and 'z are also valid. 41 | // I prefer to assign a default value to 'out' instead of using a 42 | // default case. 43 | case (sel) 44 | 4'h0: out = a; 45 | 4'h1: out = b; 46 | 4'h2: out = c; 47 | 4'h3: out = d; 48 | 4'h4: out = e; 49 | 4'h5: out = f; 50 | 4'h6: out = g; 51 | 4'h7: out = h; 52 | 4'h8: out = i; 53 | endcase 54 | end 55 | 56 | endmodule 57 | */ 58 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.3 Shift Registers/3.2.3.4 5-bit LFSR.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input clk, 3 | input reset, // Active-high synchronous reset to 5'h1 4 | output [4:0] q 5 | ); 6 | always @(posedge clk) begin 7 | if (reset) 8 | q <= 5'h1; 9 | else 10 | q <= {q[0],q[4],q[3]^q[0],q[2],q[1]}; 11 | end 12 | 13 | endmodule 14 | 15 | /* 16 | module top_module( 17 | input clk, 18 | input reset, 19 | output reg [4:0] q); 20 | 21 | reg [4:0] q_next; // q_next is not a register 22 | 23 | // Convenience: Create a combinational block of logic that computes 24 | // what the next value should be. For shorter code, I first shift 25 | // all of the values and then override the two bit positions that have taps. 26 | // A logic synthesizer creates a circuit that behaves as if the code were 27 | // executed sequentially, so later assignments override earlier ones. 28 | // Combinational always block: Use blocking assignments. 29 | always @(*) begin 30 | q_next = q[4:1]; // Shift all the bits. This is incorrect for q_next[4] and q_next[2] 31 | q_next[4] = q[0]; // Give q_next[4] and q_next[2] their correct assignments 32 | q_next[2] = q[3] ^ q[0]; 33 | end 34 | 35 | 36 | // This is just a set of DFFs. I chose to compute the connections between the 37 | // DFFs above in its own combinational always block, but you can combine them if you wish. 38 | // You'll get the same circuit either way. 39 | // Edge-triggered always block: Use non-blocking assignments. 40 | always @(posedge clk) begin 41 | if (reset) 42 | q <= 5'h1; 43 | else 44 | q <= q_next; 45 | end 46 | 47 | endmodule 48 | */ 49 | 50 | 51 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.5 Finite State Machines/3.2.5.1 FSM1_ar.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input in, 4 | input areset, 5 | output out 6 | ); 7 | 8 | // Give state names and assignments. I'm lazy, so I like to use decimal numbers. 9 | // It doesn't really matter what assignment is used, as long as they're unique. 10 | parameter A=0, B=1; 11 | reg state; // Ensure state and next are big enough to hold the state encoding. 12 | reg next; 13 | 14 | 15 | // A finite state machine is usually coded in three parts: 16 | // State transition logic 17 | // State flip-flops 18 | // Output logic 19 | // It is sometimes possible to combine one or more of these blobs of code 20 | // together, but be careful: Some blobs are combinational circuits, while some 21 | // are clocked (DFFs). 22 | 23 | 24 | // Combinational always block for state transition logic. Given the current state and inputs, 25 | // what should be next state be? 26 | // Combinational always block: Use blocking assignments. 27 | always@(*) begin 28 | case (state) 29 | A: next = in ? A : B; 30 | B: next = in ? B : A; 31 | endcase 32 | end 33 | 34 | 35 | 36 | // Edge-triggered always block (DFFs) for state flip-flops. Asynchronous reset. 37 | always @(posedge clk, posedge areset) begin 38 | if (areset) state <= B; // Reset to state B 39 | else state <= next; // Otherwise, cause the state to transition 40 | end 41 | 42 | 43 | 44 | // Combinational output logic. In this problem, an assign statement is the simplest. 45 | // In more complex circuits, a combinational always block may be more suitable. 46 | assign out = (state==B); 47 | 48 | 49 | endmodule 50 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.5 Finite State Machines/3.2.5.13 Lemmings 4.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input clk, 3 | input areset, // Freshly brainwashed Lemmings walk left. 4 | input bump_left, 5 | input bump_right, 6 | input ground, 7 | input dig, 8 | output walk_left, 9 | output walk_right, 10 | output aaah, 11 | output digging ); 12 | 13 | parameter L=0,R=1,LF=2,RF=3, LD=4, RD =5, SP = 6; 14 | reg [2:0] state, next_state; 15 | int second; 16 | 17 | always @(*) begin 18 | case(state) 19 | L: next_state = (~ground)? LF : (dig)? LD : (bump_left)? R : L; 20 | R: next_state = (~ground)? RF : (dig)? RD : (bump_right)? L : R; 21 | LF: next_state = (~ground)? LF : (second > 19)? SP : L; 22 | RF: next_state = (~ground)? RF : (second > 19)? SP : R; 23 | LD: next_state = (ground)? LD : LF; 24 | RD: next_state = (ground)? RD : RF; 25 | SP: next_state = SP; 26 | endcase 27 | end 28 | 29 | always @ (posedge clk or posedge areset) begin 30 | if(areset) begin 31 | state <= L; 32 | second = 0; 33 | end 34 | else begin 35 | state <= next_state; 36 | if ((state == LF) || (state == RF)) 37 | second = second + 1; 38 | else if (second > 20) 39 | second = 20; 40 | else 41 | second = 0; // have to reset counter 42 | end 43 | end 44 | 45 | assign aaah = ((state == LF) || (state == RF)) ; 46 | assign walk_left = (state == L); 47 | assign walk_right = (state == R); 48 | assign digging = ((state == LD) || (state == RD)); 49 | 50 | endmodule 51 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.4 More Circuits/3.2.4.3 Conway's Game of Life.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input clk, 3 | input load, 4 | input [255:0] data, 5 | output [255:0] q ); 6 | 7 | reg [255:0] temp; 8 | wire [287:0] map = {temp[15:0],temp,temp[255:240]}; 9 | int count; 10 | 11 | always@(posedge clk) begin 12 | if(load) begin 13 | q <= data; 14 | end 15 | else begin 16 | for (int i = 16; i < 272; i = i+1) begin 17 | if(i == 16 || i == 32 || i == 48 || i == 64 || i == 80 || i == 96 || i==112 || i==128 || i == 144 18 | || i == 160 || i == 176 || i == 192 || i == 208 || i == 224 || i == 240 || i == 256) begin 19 | count = map[i+1]+map[i+15]+map[i+16]+map[i+17]+map[i+31]+map[i-1]+map[i-15]+map[i-16]; 20 | end 21 | else if (i == 31 || i == 47 || i == 63 || i == 79 || i == 95 || i==111 || i==127 || i == 143 22 | || i == 159 || i == 175 || i == 191 || i == 207 || i == 223 || i == 239 || i == 255 || i == 271) begin 23 | count = map[i-1]+map[i-15]+map[i-16]+map[i-17]+map[i-31]+map[i+1]+map[i+15]+map[i+16]; 24 | end 25 | else begin 26 | count = map[i+1]+map[i+15]+map[i+16]+map[i+17]+map[i-1]+map[i-15]+map[i-16]+map[i-17]; 27 | end 28 | 29 | if(count == 2) 30 | q[i-16] <= q[i-16]; 31 | else if(count == 3) 32 | q[i-16] <= 1'b1; 33 | else 34 | q[i-16] <= 1'b0; 35 | end 36 | end 37 | 38 | end 39 | 40 | always@(negedge clk) begin 41 | temp <= q; 42 | end 43 | endmodule 44 | -------------------------------------------------------------------------------- /3 Circuit/3.3 Building Larger Circuits/3.3.6 Complete Timer.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input reset, // Synchronous reset 4 | input data, 5 | output [3:0] count, 6 | output counting, 7 | output done, 8 | input ack ); 9 | 10 | parameter S=0,S1=1,S11=2,S110=3, B0=4, B1=5, B2=6, B3=7, cnt=8, delay_cnt=9, last_cnt=10, hold=11; 11 | reg[3:0] state, next, delay; 12 | reg[9:0] thousand; 13 | reg[3:0] counter; 14 | 15 | always@ (*) begin 16 | case(state) 17 | S: next = (data)? S1 : S; 18 | S1: next = (data)? S11: S; 19 | S11: next = (~data)? S110:S11; 20 | S110: next = (data)? B0 : S; 21 | B0: begin next = B1; 22 | delay[3] = data; 23 | end 24 | B1: begin next = B2; 25 | delay[2] = data; 26 | end 27 | B2: begin next = B3; 28 | delay[1] = data; 29 | end 30 | B3: begin next = cnt; 31 | delay[0] = data; 32 | end 33 | cnt: next = (delay == 4'd0)? last_cnt : (thousand == 10'd998)? delay_cnt : cnt; 34 | delay_cnt: next = (counter == 4'd1)? last_cnt : cnt; // one clock count 35 | last_cnt: next = (thousand == 10'd999)? hold:last_cnt; 36 | hold: next = (ack)? S:hold; 37 | endcase 38 | end 39 | 40 | always@ (posedge clk) begin 41 | if (state == B3) begin 42 | counter <= {delay[3:1],data}; 43 | thousand <= 0; 44 | end 45 | if (state == cnt || state == last_cnt) 46 | thousand <= thousand + 1'b1; 47 | if (state == delay_cnt) begin 48 | thousand <= 0; 49 | counter <= counter - 1'b1; 50 | end 51 | end 52 | 53 | 54 | always@(posedge clk) begin 55 | if (reset) 56 | state <= S; 57 | else begin 58 | state <= next; 59 | end 60 | end 61 | 62 | assign counting = (state == cnt) || (state == delay_cnt) || (state == last_cnt); 63 | assign done = (state == hold); 64 | assign count = counter; 65 | 66 | endmodule 67 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.2 Counters/3.2.2.8 12-hour clock.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input clk, 3 | input reset, 4 | input ena, 5 | output pm, 6 | output [7:0] hh, 7 | output [7:0] mm, 8 | output [7:0] ss); 9 | 10 | always@(posedge clk) begin 11 | if (reset) begin 12 | hh <= 8'h12; 13 | mm <= 0; 14 | ss <= 0; 15 | pm <= 0; 16 | end 17 | else begin 18 | if (ena) begin 19 | pm <= (hh == 8'h11 && mm == 8'h59 && ss == 8'h59)? ~pm : pm; 20 | if (ss == 8'h59) begin // ss = 59 21 | ss <= 0; 22 | 23 | if (mm == 8'h59) begin // mm = 59 24 | mm <= 0; 25 | 26 | if (hh == 8'h12) begin 27 | hh <= 8'h01; 28 | end 29 | 30 | else begin 31 | if (hh[3:0] == 4'd9) begin 32 | hh[3:0] <= 0; 33 | hh[7:4] <= hh[7:4] + 4'd1; 34 | end 35 | else 36 | hh[3:0] <= hh[3:0] + 4'd1; 37 | end 38 | 39 | end 40 | else begin 41 | if (mm[3:0] == 4'd9) begin 42 | mm[3:0] <= 0; 43 | mm[7:4] <= mm[7:4] + 4'd1; 44 | end 45 | else 46 | mm[3:0] <= mm[3:0] + 4'd1; 47 | end 48 | 49 | 50 | end 51 | else begin 52 | if (ss[3:0] == 4'd9) begin 53 | ss[3:0] <= 0; 54 | ss[7:4] <= ss[7:4] + 4'd1; 55 | end 56 | else 57 | ss[3:0] <= ss[3:0] + 4'd1; 58 | end 59 | end 60 | end 61 | 62 | 63 | end 64 | 65 | 66 | 67 | endmodule 68 | -------------------------------------------------------------------------------- /3 Circuit/3.2 Sequential Logic/3.2.5 Finite State Machines/3.2.5.21 Q8 Mealy FSM.v: -------------------------------------------------------------------------------- 1 | module top_module ( 2 | input clk, 3 | input aresetn, // Asynchronous active-low reset 4 | input x, 5 | output z ); 6 | 7 | parameter a=0,b=1,c=2; 8 | reg[1:0] state, next; 9 | 10 | always@(*) begin 11 | case(state) 12 | a: next = (x)? b : a; 13 | b: next = (x)? b : c; 14 | c: next = (x)? b : a; 15 | endcase 16 | end 17 | 18 | always@(posedge clk or negedge aresetn) begin 19 | if(!aresetn) 20 | state <= a; 21 | else 22 | state <= next; 23 | end 24 | 25 | assign z = (state == c) & x; 26 | 27 | endmodule 28 | 29 | /* 30 | module top_module ( 31 | input clk, 32 | input aresetn, 33 | input x, 34 | output reg z 35 | ); 36 | 37 | // Give state names and assignments. I'm lazy, so I like to use decimal numbers. 38 | // It doesn't really matter what assignment is used, as long as they're unique. 39 | parameter S=0, S1=1, S10=2; 40 | reg[1:0] state, next; // Make sure state and next are big enough to hold the state encodings. 41 | 42 | 43 | 44 | // Edge-triggered always block (DFFs) for state flip-flops. Asynchronous reset. 45 | always@(posedge clk, negedge aresetn) 46 | if (!aresetn) 47 | state <= S; 48 | else 49 | state <= next; 50 | 51 | 52 | 53 | // Combinational always block for state transition logic. Given the current state and inputs, 54 | // what should be next state be? 55 | // Combinational always block: Use blocking assignments. 56 | always@(*) begin 57 | case (state) 58 | S: next = x ? S1 : S; 59 | S1: next = x ? S1 : S10; 60 | S10: next = x ? S1 : S; 61 | default: next = 'x; 62 | endcase 63 | end 64 | 65 | 66 | 67 | // Combinational output logic. I used a combinational always block. 68 | // In a Mealy state machine, the output depends on the current state *and* 69 | // the inputs. 70 | always@(*) begin 71 | case (state) 72 | S: z = 0; 73 | S1: z = 0; 74 | S10: z = x; // This is a Mealy state machine: The output can depend (combinational) on the input. 75 | default: z = 1'bx; 76 | endcase 77 | end 78 | 79 | endmodule 80 | 81 | */ 82 | -------------------------------------------------------------------------------- /2 Verilog Language/2.2 Vectors/2.2.7 vector_reversal_1.v: -------------------------------------------------------------------------------- 1 | module top_module( 2 | input [7:0] in, 3 | output [7:0] out 4 | ); 5 | assign out[7:0] = {in[0],in[1],in[2],in[3],in[4],in[5],in[6],in[7]}; 6 | 7 | /* 8 | // I know you're dying to know how to use a loop to do this: 9 | 10 | // Create a combinational always block. This creates combinational logic that computes the same result 11 | // as sequential code. for-loops describe circuit *behaviour*, not *structure*, so they can only be used 12 | // inside procedural blocks (e.g., always block). 13 | // The circuit created (wires and gates) does NOT do any iteration: It only produces the same result 14 | // AS IF the iteration occurred. In reality, a logic synthesizer will do the iteration at compile time to 15 | // figure out what circuit to produce. (In contrast, a Verilog simulator will execute the loop sequentially 16 | // during simulation.) 17 | always @(*) begin 18 | for (int i=0; i<8; i++) // int is a SystemVerilog type. Use integer for pure Verilog. 19 | out[i] = in[8-i-1]; 20 | end 21 | 22 | 23 | // It is also possible to do this with a generate-for loop. Generate loops look like procedural for loops, 24 | // but are quite different in concept, and not easy to understand. Generate loops are used to make instantiations 25 | // of "things" (Unlike procedural loops, it doesn't describe actions). These "things" are assign statements, 26 | // module instantiations, net/variable declarations, and procedural blocks (things you can create when NOT inside 27 | // a procedure). Generate loops (and genvars) are evaluated entirely at compile time. You can think of generate 28 | // blocks as a form of preprocessing to generate more code, which is then run though the logic synthesizer. 29 | // In the example below, the generate-for loop first creates 8 assign statements at compile time, which is then 30 | // synthesized. 31 | // Note that because of its intended usage (generating code at compile time), there are some restrictions 32 | // on how you use them. Examples: 1. Quartus requires a generate-for loop to have a named begin-end block 33 | // attached (in this example, named "my_block_name"). 2. Inside the loop body, genvars are read only. 34 | generate 35 | genvar i; 36 | for (i=0; i<8; i = i+1) begin: my_block_name 37 | assign out[i] = in[8-i-1]; 38 | end 39 | endgenerate 40 | */ 41 | endmodule 42 | -------------------------------------------------------------------------------- /Tips.md: -------------------------------------------------------------------------------- 1 | # Some useful tips 2 | 3 | ## Vector 4 | 5 | Vectors must be declared as: 6 | 7 | ``` verilog 8 | type [upper:lower] vector_name; 9 | ``` 10 | 11 | Here are some examples: 12 | 13 | ``` verilog 14 | wire [7:0] w; // 8-bit wire 15 | reg [4:1] x; // 4-bit reg 16 | output reg [0:0] y; // 1-bit reg that is also an output port (this is still a vector) 17 | input wire [3:-2] z; // 6-bit wire input (negative ranges are allowed) 18 | output [3:0] a; // 4-bit output wire. Type is 'wire' unless specified otherwise. 19 | wire [0:7] b; // 8-bit wire where b[0] is the most-significant bit. 20 | ``` 21 | 22 | * notice that the negative ranges are allowed 23 | * writing `vec[0:3]` when *vec* is declared `wire [3:0] vec` is illegal 24 | 25 | Implicit nets 26 | 27 | ``` verilog 28 | wire [2:0] a, c; // Two vectors 29 | assign a = 3'b101; // a = 101 30 | assign b = a; // b = 1 implicitly-created wire 31 | assign c = b; // c = 001 <-- bug 32 | my_module i1 (d,e); // d and e are implicitly one-bit wide if not declared. 33 | // This could be a bug if the port was intended to be a vector. 34 | ``` 35 | 36 | Unpacked vs. Packed Arrays 37 | 38 | ``` verilog 39 | reg [7:0] mem [255:0]; // 256 unpacked elements, each of which is a 8-bit packed vector of reg. 40 | reg mem2 [28:0]; // 29 unpacked elements, each of which is a 1-bit reg. 41 | ``` 42 | 43 | Part-Select 44 | 45 | ``` verilog 46 | w[3:0] // Only the lower 4 bits of w 47 | x[1] // The lowest bit of x 48 | x[1:1] // ...also the lowest bit of x 49 | z[-1:-2] // Two lowest bits of z 50 | b[3:0] // Illegal. Vector part-select must match the direction of the declaration. 51 | b[0:3] // The *upper* 4 bits of b. 52 | assign w[3:0] = b[0:3]; // Assign upper 4 bits of b to lower 4 bits of w. w[3]=b[0], w[2]=b[1], etc. 53 | ``` 54 | 55 | Concatenation operator 56 | 57 | ``` verilog 58 | input [15:0] in; 59 | output [23:0] out; 60 | assign {out[7:0], out[15:8]} = in; // Swap two bytes. Right side and left side are both 16-bit vectors. 61 | assign out[15:0] = {in[7:0], in[15:8]}; // This is the same thing. 62 | assign out = {in[7:0], in[15:8]}; // This is different. The 16-bit vector on the right is extended to 63 | // match the 24-bit vector on the left, so out[23:16] are zero. 64 | // In the first two examples, out[23:16] are not assigned. 65 | ``` 66 | 67 | Bitwise Operator (2.2.4) 68 | 69 | A bitwise operation between two N-bit vectors replicates the operation for each bit of the vector and produces a N-bit output, while a logical operation treats the entire vector as a boolean value (true = non-zero, false = zero) and produces a 1-bit output. 70 | 71 | bitwise: ```|``` 72 | operation: ```||``` 73 | 74 | Replication Operator (2.2.8) 75 | 76 | Examples: 77 | 78 | ```verilog 79 | {5{1'b1}} // 5'b11111 (or 5'd31 or 5'h1f) 80 | {2{a,b,c}} // The same as {a,b,c,a,b,c} 81 | {3'd5, {2{3'd6}}} // 9'b101_110_110. It's a concatenation of 101 with 82 | // the second vector, which is two copies of 3'b110. 83 | ``` 84 | 85 | ## Modules Hierachy 86 | 87 | Connecting Signals to Module Ports 88 | 89 | By position 90 | 91 | ``` verilog 92 | mod_a instance1(wa, wb, wc); 93 | ``` 94 | 95 | By name 96 | 97 | ``` verilog 98 | mod_a instance2( .out(wc), .in1(wa), .in2(wb)); 99 | ``` 100 | 101 | ## Procedures (Always block) 102 | 103 | [casez explaination](https://hdlbits.01xz.net/wiki/Always_casez) 104 | 105 | 3.1.2.3 9-to-1 mux: another way to write default in case block 106 | 107 | ``` verilog 108 | always @(*) begin 109 | out = '1; // '1 is a special literal syntax for a number with all bits set to 1. 110 | // '0, 'x, and 'z are also valid. 111 | // I prefer to assign a default value to 'out' instead of using a 112 | // default case. 113 | case (sel) 114 | ... 115 | endcase 116 | end 117 | ``` 118 | 119 | 3.2.1 Several Edge Detectors 120 | 121 | 3.2.2 Several Counters 122 | 123 | 3.2.3.4 A systmetic way to write SR 124 | 125 | **3.2.4.3 Conway's Game:** 126 | The idea is to extend the top row of the original map with the lasp row, vice versa. In this case, I found that the up, down, left, right indices are associated with certain bit shift with unique pattern. The up/down right and up/down left are with some symmetric pattern shift. 127 | 128 | **3.2.5 FSM CODING STANDARD** 129 | A finite state machine is usually coded in three parts: 130 | 131 | * State transition logic 132 | * State flip-flops 133 | * Output logic 134 | 135 | It is sometimes possible to combine one or more of these blobs of code 136 | together, but be careful: Some blobs are combinational circuits, while some are clocked (DFFs) 137 | 138 | A sample version can be found at 3.2.5.1 139 | --------------------------------------------------------------------------------