Chapter 3 Code

To comply the Chapter 3 Verilog codes within the book titled Fundamental Digital Circuits and FPGA

Section 3.1: Three-input XOR Gate

Module Definition

Verilog Code

Code 3.1: Construction of a 3-input XOR Gate circuit using the Gate-level description method
/*--------------------------------------------------------------------------------------------------- 	
*- File name: 		XOR3_1.v
*- Top Module name: 	XOR3_1
  - Submodules:		xor (Verilog built-in primitive gates)
*- Description:		Implementation of a 3 input XOR gate
*- 
*- Example of Usage:
	You can implement this code on all variants of STEPFPGA family boards. 
	If you want to implement this code on board and observe the logic behaviors: 
		- assign A, B, C to 3 on-board switches
		- assign Y to any on-board LEDs

*- Copyright of this code: MIT License
--------------------------------------------------------------------------------------------------- */
module XOR3_1 (       
    input wire  A,    
    input wire  B,    
    input wire  C,    
    output wire Y     
) ;                      
    xor  (Y, A, B, C) ;   
endmodule            

Implementation

Section 3.2: One-bit Full Adder

Module Definition

Verilog Code

Written in Data-flow Description style

Code 3.2: Constructing a 1-bit Full Adder
/*--------------------------------------------------------------------------------------------------- 	
*- File name: 		full_adder.v
*- Top Module name: 	full_adder
  - Submodules:		N/A
*- Description:		Implementation of a 1-bit Full Binary Adder
*- 
*- Example of Usage:
	You can implement this code on all variants of STEPFPGA family boards. 
	If you want to implement this code on board and observe the logic behaviors: 
		- assign a, b, cin to 3 on-board switches
		- assign sum, co to any 2 on-board LEDs
		
*- Copyright of this code: MIT License
--------------------------------------------------------------------------------------------------- */

module full_adder (
   input wire a,           
   input wire b,  
   input wire cin,  
   output wire sum,         
   output wire co
); 
   assign sum = a^b^cin;
   assign co = ((a^b)&cin)|(a&b);
endmodule

Written in Structrual (Gate) Level Description style

module full_adder (
   input wire a,           
   input wire b,  
   input wire cin,  
   output wire sum,         
   output wire co
); 

   // XOR gates for sum
   wire xor_ab, xor_abc;
   xor (xor_ab, a, b);
   xor (xor_abc, xor_ab, cin);
   
   // AND & OR gates for carry out
   wire and_ab, and_xor_ab_cin, or_final;
   and (and_ab, a, b);
   and (and_xor_ab_cin, xor_ab, cin);
   or (or_final, and_ab, and_xor_ab_cin);

   // Assignments
   assign sum = xor_abc;
   assign co = or_final;

endmodule

Implementation

Section 3.3: Two by Four Decoder

Module Definition

Verilog Code

Code 3.3: Construction of a complete 2-4 Decoder
/*--------------------------------------------------------------------------------------------------- 	
*- File name: 		decoder24.v
*- Top Module name: 	decoder24_en
  - Submodules:		N/A
*- Description:		Implementation of a 2-4 decoder module (without Enable)
*- 
*- Example of Usage:
	You can implement this code on all variants of STEPFPGA family boards. 
	If you want to implement this code on board and observe the logic behaviors: 
		- assign A[1] , A[0] to 2 on-board switches
		- assign Y[3]...Y[0] to 4 on-board LEDs 
	
*- Copyright of this code: MIT License
--------------------------------------------------------------------------------------------------- */

module decoder24 (
   input      [1: 0] A,          
   output reg [3: 0] Y           
); 

always @  (A)  begin
    case  (A)  
        2'b00:  Y = 4'b0001;     
        2'b01:  Y = 4'b0010; 
        2'b10:  Y = 4'b0100; 
        2'b11:  Y = 4'b1000; 
    endcase
end
endmodule

Implementation

Section 3.4: Three by Eight Decoder

Module Definition

Verilog Code

Code 3.4: Behavioral description of a 2-4 Decoder with enable input signal
/*--------------------------------------------------------------------------------------------------- 	
*- File name: 		decoder38.v
*- Top Module name: 	decoder38
  - Submodules:		decoder24_en upper
*- Description:		Implementation of a 3-8 decoder module
*- 
*- Example of Usage:
	You can implement this code on all variants of STEPFPGA family boards. 
	If you want to implement this code on board and observe the logic behaviors: 
		- assign X[2] ... X[0] to 3 on-board switches
		- assign D[7] ... D[0] to 8 on-board LEDs 
		
*- Copyright of this code: MIT License
--------------------------------------------------------------------------------------------------- */

module decoder38
(
  input wire [2: 0] X, 
  output wire [7: 0] D
) ; 

decoder24_en upper (
      .A   (X[1: 0]) ,      
      .EN  (X[2]) ,         
      .Y   (D[7: 4])       
) ; 

decoder24_en lower (
      .A   (X[1: 0]) ,      
      .EN  (!X[2]) ,        
      .Y   (D[3: 0])       
) ;  
endmodule

module decoder24_en   (
    input wire [1:0] A,             
    input wire EN,                  
    output reg [3:0] Y              
); 

always @ (EN,  A) begin
    if (EN == 1'b1)               
        case (A)  
            2'b00: Y = 4'b0001; 
            2'b01: Y = 4'b0010; 
            2'b10: Y = 4'b0100; 
            2'b11: Y = 4'b1000; 
        endcase     
    else                            
        Y = 4'b0000; 
end
endmodule

Implementation

Section 3.5: Seven segment display

Module Definition

Verilog Code

Code 3.6: Common Cathode 7-segment driver
/*--------------------------------------------------------------------------------------------------- 	
*- File name: 		segment7.v
*- Top Module name: 	segment7
  - Submodules:		N/A
*- Description:		Implementation of a 7-segment display driver (common cathod)
*- 
*- Example of Usage:
	You can implement this code on all variants of STEPFPGA family boards. 
	If you want to implement this code on board and observe the logic behaviors: 
		- assign seg_data[3]...seg_data[0] to the 4 on-board swiches
		- assign segment_led[8] to SEG, segment_led[7] to DP
		- assign segment_led[6]...segment_led[0] to 'g, f, ... a' accordingly

* - Additional comments: 	 
   If you want to display decimal numbers only, the 4-bit input data must be in BCD converted
   form; will explain in Chapter 5 when implement the Elevator project. 

*- Copyright of this code: MIT License
--------------------------------------------------------------------------------------------------- */

module segment7 (
    input  wire [3:0] seg_data,        
    output reg  [8:0] segment_led  
    //  MSB~LSB = SEG,  DP,  g,  f e,  d,  c,  b,  a
) ; 
always @  (seg_data)  begin
    case  (seg_data) 
      4'b0000: segment_led = 9'h3f;   //  0
      4'b0001: segment_led = 9'h06;   //  1
      4'b0010: segment_led = 9'h5b;   //  2
      4'b0011: segment_led = 9'h4f;   //  3
      4'b0100: segment_led = 9'h66;   //  4
      4'b0101: segment_led = 9'h6d;   //  5
      4'b0110: segment_led = 9'h7d;   //  6
      4'b0111: segment_led = 9'h07;   //  7
      4'b1000: segment_led = 9'h7f;   //  8
      4'b1001: segment_led = 9'h6f;   //  9
      4'b1010: segment_led = 9'h77;   //  A
      4'b1011: segment_led = 9'h7C;   //  b
      4'b1100: segment_led = 9'h39;   //  C
      4'b1101: segment_led = 9'h5e;   //  d
      4'b1110: segment_led = 9'h79;   //  E
      4'b1111: segment_led = 9'h71;   //  F
    endcase
 end
endmodule

Implementation

Section 3.6: Decimal counter

Illustration

Verilog Code

Code 3.6: Using four counters to control the on-off time of four LED lights respectively
/*--------------------------------------------------------------------------------------------------- 	
*- File name: 		LED_sequence.v
*- Top Module name: 	LED_sequence
  - Submodules:		N/A
*- Description:		Experiment with counters
*- 
*- Example of Usage:
	You can implement this code on all variants of STEPFPGA family boards. 
	If you want to implement this code on board and observe the logic behaviors: 
		- assign clk to PCLK (12MHz) on-board clock
		- assign rst_n to any push-buttons on-board
		- assign led[3] ... led[0] to 4 on-board LEDs

*- Copyright of this code: MIT License
--------------------------------------------------------------------------------------------------- */

module LED_sequence   (
    input       clk,             
    input       rst_n,           
    output      [3:0] led
) ; 

reg [25: 0] cnt;                 
parameter t_1s = 12_000_000,     
          t_2s = 24_000_000,     
          t_3s = 36_000_000,     
          t_4s = 48_000_000;     
           
always @  (posedge clk or negedge rst_n)  begin   
    if  (!rst_n)  
        cnt <= 0;               
    else
        cnt <= cnt + 1'b1;      
end

assign led[0] =  (cnt < t_1s)  ? 1 : 0;        // Conditional assignment
assign led[1] =  (cnt < t_2s)  ? 1 : 0;        // If (true), assign to 1; otherwise assign to 0
assign led[2] =  (cnt < t_3s)  ? 1 : 0;         
assign led[3] =  (cnt < t_4s)  ? 1 : 0;       

endmodule
A simple D-Flipflop
/*--------------------------------------------------------------------------------------------------- 	
*- File name: 		dff.v
*- Top Module name: 	dff
  - Submodules:		N/A
*- Description:		Implementation of a 1-bit D Flip-Flop
*- 
*- Example of Usage:
	You can implement this code on all variants of STEPFPGA family boards. 
	If you want to implement this code on board and observe the logic behaviors: 
		- assign clk to PCLK signal (12MHz)
		- assign D to any on-board switches
		- assign Q to any on-board LEDs 
		
*- Copyright of this code: MIT License
--------------------------------------------------------------------------------------------------- */
module dff(input clk, D, output reg Q);
    always @ (posedge clk) begin
        Q <= D;
    end
endmodule

Implementation

Section 3.7: Frequency divider

Illustration

Verilog Code

Code 3.7: Frequency division by any integer
/* 	
File name: divider_integer
Module Function: Implementation of a clock frequency divider

This code implements a clock divider which supports for all integer divisors. 
Note: if the divisor is 'odd' number, the output duty cycle is not exactly 50%; but if the divider is higher than
99 you can practically neglect this.

Copyright License: MIT
*/

// To set for different divisor, you only need to change these two parameters
module divider_integer # (           
    parameter   N     = 12000000,	// the divisor
    parameter   WIDTH = 24 		// the minimum bit-width to hold this divisor
)  
(
    input clk,
    output reg clkout 
);
reg [WIDTH-1:0] cnt; 
always @ (posedge clk) begin
    if(cnt>=(N-1))
        cnt <= 1'b0;
    else
        cnt <= cnt + 1'b1;
    clkout <= (cnt<N/2)?1'b1:1'b0;
end
endmodule

Implementation

Last updated