├── .DS_Store ├── Delay_Modelling_Verilog └── README.md ├── Docs ├── .DS_Store ├── Images │ ├── .DS_Store │ ├── button_go_back.png │ ├── button_run-on-eda-playground.png │ ├── dff.png │ ├── full_adder.png │ └── half_adder.png └── Video_Gesture_Glove.mp4 ├── FIFO ├── README.md ├── Screen Shot 2021-06-12 at 6.06.44 PM.png ├── fifo_sync.png └── fifo_sync_wave.png ├── Fibonacci ├── README.md ├── Screen Shot 2021-06-14 at 11.42.32 PM.png └── fibonacci_counter.png ├── Frequency_Dividers ├── .DS_Store ├── README.md ├── div_by_11_table.png ├── div_by_12_table.png ├── div_by_2.png ├── div_by_2.v ├── div_by_3_waveform.png ├── div_by_4_waveform.png ├── div_by_5_table.png ├── div_by_5_waveform.png ├── div_by_6_table.png ├── div_by_6_waveform.png ├── div_by_9_table.png └── div_by_9_waveform.png ├── Gray_Counter ├── .DS_Store ├── README.md ├── gray_code_table.png ├── gray_counter.png ├── gray_counter_basic.png └── gray_counter_wave.png ├── LIFO └── README.md ├── Mod-N_Counter └── README.md ├── PISO ├── PISO.v ├── README.md ├── piso.png └── piso_block.png ├── README.md ├── Register_File ├── .DS_Store ├── README.md ├── RegisterFile.v ├── RegisterFile_tb.v ├── reg_file_wave.png └── register_file.png ├── Round_Robin_Arbiter └── README.md ├── SIPO ├── .DS_Store ├── README.md ├── SIPO.v ├── SIPO_tb.v ├── sipo_basic.png └── sipo_capture_reg.png ├── Sequence_Detector ├── .DS_Store ├── README.md ├── mealy_1010_non_overlap.png ├── mealy_1010_overlap.png ├── moore_1010_non_overlap.png ├── moore_1010_overlap.png ├── seqD_1001.png ├── seqD_1010.png ├── seqD_1010_ROM.jpg ├── seqD_1010_ROM1.png ├── seqD_1010_ROM_SM.png └── seqD_1010_shiftReg.png ├── Shifter_Rotator ├── .DS_Store ├── README.md ├── right_left_rotator.png ├── right_left_shifter.png ├── right_rotator.png ├── right_shifter.png └── shifter_rotator.png ├── Sorting_Network ├── .DS_Store ├── README.md ├── cas_block.png ├── sorting_network_4nos.png ├── sorting_network_8nos.png └── sorting_network_blocks.png ├── _config.yml ├── about.md └── index.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/.DS_Store -------------------------------------------------------------------------------- /Delay_Modelling_Verilog/README.md: -------------------------------------------------------------------------------- 1 | # Verilog 2 | Logic Design using Verilog 3 | -------------------------------------------------------------------------------- /Docs/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Docs/.DS_Store -------------------------------------------------------------------------------- /Docs/Images/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Docs/Images/.DS_Store -------------------------------------------------------------------------------- /Docs/Images/button_go_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Docs/Images/button_go_back.png -------------------------------------------------------------------------------- /Docs/Images/button_run-on-eda-playground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Docs/Images/button_run-on-eda-playground.png -------------------------------------------------------------------------------- /Docs/Images/dff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Docs/Images/dff.png -------------------------------------------------------------------------------- /Docs/Images/full_adder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Docs/Images/full_adder.png -------------------------------------------------------------------------------- /Docs/Images/half_adder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Docs/Images/half_adder.png -------------------------------------------------------------------------------- /Docs/Video_Gesture_Glove.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Docs/Video_Gesture_Glove.mp4 -------------------------------------------------------------------------------- /FIFO/README.md: -------------------------------------------------------------------------------- 1 | # Verilog 2 | Logic Design using Verilog 3 | -------------------------------------------------------------------------------- /FIFO/Screen Shot 2021-06-12 at 6.06.44 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/FIFO/Screen Shot 2021-06-12 at 6.06.44 PM.png -------------------------------------------------------------------------------- /FIFO/fifo_sync.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/FIFO/fifo_sync.png -------------------------------------------------------------------------------- /FIFO/fifo_sync_wave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/FIFO/fifo_sync_wave.png -------------------------------------------------------------------------------- /Fibonacci/README.md: -------------------------------------------------------------------------------- 1 | # Verilog 2 | Logic Design using Verilog 3 | -------------------------------------------------------------------------------- /Fibonacci/Screen Shot 2021-06-14 at 11.42.32 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Fibonacci/Screen Shot 2021-06-14 at 11.42.32 PM.png -------------------------------------------------------------------------------- /Fibonacci/fibonacci_counter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Fibonacci/fibonacci_counter.png -------------------------------------------------------------------------------- /Frequency_Dividers/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Frequency_Dividers/.DS_Store -------------------------------------------------------------------------------- /Frequency_Dividers/README.md: -------------------------------------------------------------------------------- 1 | # Verilog 2 | Logic Design using Verilog 3 | -------------------------------------------------------------------------------- /Frequency_Dividers/div_by_11_table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Frequency_Dividers/div_by_11_table.png -------------------------------------------------------------------------------- /Frequency_Dividers/div_by_12_table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Frequency_Dividers/div_by_12_table.png -------------------------------------------------------------------------------- /Frequency_Dividers/div_by_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Frequency_Dividers/div_by_2.png -------------------------------------------------------------------------------- /Frequency_Dividers/div_by_2.v: -------------------------------------------------------------------------------- 1 | module div_by_2(input clk, rst, 2 | output div); 3 | 4 | reg Q; 5 | 6 | always @ (posedge clk) begin 7 | if (rst) 8 | Q <= 1'b0; 9 | else 10 | Q <= ~Q; 11 | end 12 | 13 | assign div = Q; 14 | 15 | endmodule 16 | -------------------------------------------------------------------------------- /Frequency_Dividers/div_by_3_waveform.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Frequency_Dividers/div_by_3_waveform.png -------------------------------------------------------------------------------- /Frequency_Dividers/div_by_4_waveform.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Frequency_Dividers/div_by_4_waveform.png -------------------------------------------------------------------------------- /Frequency_Dividers/div_by_5_table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Frequency_Dividers/div_by_5_table.png -------------------------------------------------------------------------------- /Frequency_Dividers/div_by_5_waveform.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Frequency_Dividers/div_by_5_waveform.png -------------------------------------------------------------------------------- /Frequency_Dividers/div_by_6_table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Frequency_Dividers/div_by_6_table.png -------------------------------------------------------------------------------- /Frequency_Dividers/div_by_6_waveform.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Frequency_Dividers/div_by_6_waveform.png -------------------------------------------------------------------------------- /Frequency_Dividers/div_by_9_table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Frequency_Dividers/div_by_9_table.png -------------------------------------------------------------------------------- /Frequency_Dividers/div_by_9_waveform.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Frequency_Dividers/div_by_9_waveform.png -------------------------------------------------------------------------------- /Gray_Counter/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Gray_Counter/.DS_Store -------------------------------------------------------------------------------- /Gray_Counter/README.md: -------------------------------------------------------------------------------- 1 | # Verilog 2 | Logic Design using Verilog 3 | -------------------------------------------------------------------------------- /Gray_Counter/gray_code_table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Gray_Counter/gray_code_table.png -------------------------------------------------------------------------------- /Gray_Counter/gray_counter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Gray_Counter/gray_counter.png -------------------------------------------------------------------------------- /Gray_Counter/gray_counter_basic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Gray_Counter/gray_counter_basic.png -------------------------------------------------------------------------------- /Gray_Counter/gray_counter_wave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Gray_Counter/gray_counter_wave.png -------------------------------------------------------------------------------- /LIFO/README.md: -------------------------------------------------------------------------------- 1 | # Verilog 2 | Logic Design using Verilog 3 | -------------------------------------------------------------------------------- /Mod-N_Counter/README.md: -------------------------------------------------------------------------------- 1 | # Verilog 2 | Logic Design using Verilog 3 | -------------------------------------------------------------------------------- /PISO/PISO.v: -------------------------------------------------------------------------------- 1 | module PISO #(parameter N = 8) (input clk, load, 2 | input [N-1:0] Din, 3 | output Dout); 4 | 5 | reg [N-1:0] Q; 6 | 7 | always @ (posedge clk) begin 8 | if (load) 9 | Q <= Din; 10 | else 11 | Q <= {1'b0, Q[N-1:1]}; 12 | end 13 | 14 | assign Dout = Q; 15 | 16 | endmodule 17 | -------------------------------------------------------------------------------- /PISO/README.md: -------------------------------------------------------------------------------- 1 | # Verilog 2 | Logic Design using Verilog 3 | -------------------------------------------------------------------------------- /PISO/piso.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/PISO/piso.png -------------------------------------------------------------------------------- /PISO/piso_block.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/PISO/piso_block.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Contents 2 | 3 | - [Types of Verilog Modelling](#types-of-verilog-modelling) 4 | 5 | - [Verilog Coding Style](#verilog-coding-style) 6 | 7 | - [Latches in Verilog](#latches-in-verilog) 8 | 9 | - [Basic hardware components](#basic-hardware-components) 10 | 11 | | [Adders](#adders) | [Shifter and Rotator](#shifter-and-rotator) | [Multiplier](#multiplier) | 12 | | ------- | ------- | ------- | 13 | | [Divider](#divider) | [Sorting network](#sorting-network) | [D flip-flop](#d-flip-flop) | 14 | | [Serial in parallel out (SIPO)](#serial-in-parallel-out-sipo) | [Parallel in serial out (PISO)](#parallel-in-serial-out-piso) | [Counters](#counters) | 15 | | [MOD-N counters](#mod-n-counters) | [Gray counter](#gray-counter) | [Fibonacci counter](#fibonacci-counter) | 16 | | [Frequency Dividers](#frequency-dividers) | [Linear feedback shift register (LFSR)](#linear-feedback-shift-register-LFSR) | [Sequence Detector](#sequence-detector) | 17 | | [Register File](#register-file) | [First-in-first-out (FIFO)](#first-in-first-out-fifo) | [Last-in-first-out (LIFO)](#last-in-first-out-lifo) | 18 | | [Round robin arbiter](#round-robin-arbiter) | | | 19 | 20 | - Single-cycle CPU 21 | 22 | - Multi-cycle CPU 23 | 24 | - Pipelined CPU 25 | 26 | - Tomasulo CPU 27 | 28 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 29 | 30 | # Types of Verilog Modelling 31 | Verilog is one of the Hardware Description Language (HDL) used to model the electronics systems at the following abstraction levels: 32 | 33 | 1. Register Transfer Level (RTL) - An abstraction level, where the circuits are modelled as the flow of data between registers. This is achieved through always blocks and assign statements. The RTL should be written in a way such that it is completely synthesizable, i.e., can be translated/synthesized to gate level 34 | 35 | 2. Behavioral - An abstraction level, which mimics the desired functionality of the hardware but is not necessarily synthesizable. Behavioral verilog is often used to represent analog block, place holder code, testbench code, and most importantly for modelling hardware for behavioral simulation. 36 | 37 | 3. Structural - Logic described by gates and modules only. No always blocks or assign statements. This is a representative of the real gates in the hardware. 38 | 39 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 40 | 41 | # Verilog Coding Style 42 | 43 | Here, we will try to create exaples of hardware using RTL model and test it using an appropriate testbench. 44 | 45 | The basic structure of code we will follow for hardware modelling the design is as follows: 46 | 47 | ```verilog 48 | module design_name (input , 49 | output ); 50 | 51 | //internal registers and wires 52 | reg ; 53 | wire ; 54 | 55 | //combinational logic for next-state-logic 56 | always @ (*) begin 57 | //Combinational Statements using blocking assignments 58 | end 59 | 60 | //sequential logic for state-memory 61 | always @ (posedge clk) begin 62 | //Sequential Statements with non-blocking assignments 63 | //Reset statement necessary 64 | end 65 | 66 | //combinational logic for output-functional-logic 67 | assign = ; 68 | endmodule 69 | ``` 70 | 71 | The basic structure of code we will follow for creating a testbench to test the design is as follows: 72 | 73 | ```verilog 74 | module design_name_tb (); 75 | 76 | //internal registers and wires 77 | reg ; // All design inputs should be registers 78 | wire ; // All design outputs can be wires 79 | 80 | //initialize the design 81 | design_name (.input_port_names(reg_names), .output_port_names(wire_names)); 82 | 83 | //If the design has clock, create a clock (here clock period = 2ns) 84 | always #1 clk = ~clk 85 | 86 | //test vectors input 87 | initial begin 88 | // initialize all inputs to initial values 89 | 90 | // write the input vectors here 91 | 92 | #5 $stop; //terminate the simulation 93 | end 94 | endmodule 95 | ``` 96 | 97 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 98 | 99 | # Latches in Verilog 100 | 101 | The latch is modelled in verilog as 102 | 103 | ```verilog 104 | module d_latch (input en, d, 105 | output q); 106 | always @ (*) begin 107 | if (clk) 108 | q = d; 109 | end 110 | endmodule 111 | ``` 112 | 113 | However, sometines a latch can be inferred in a verilog code unexpectedly due to incorrect coding practice such as when a combinational logic has undefined states. These can be - 114 | 1. Signal missing in the sensitivity list 115 | 116 | ```verilog 117 | always @(a or b) 118 | begin 119 | out = a + b + c; // Here, a latch is inferred for c, 120 | // since it is missing from sensitivity list 121 | end 122 | ``` 123 | 124 | 125 | 2. Coverage not provided for all cases in an if-statement or case-statement 126 | 127 | In the following case , we have a case where q = d for en = 1. However, the tool does not know what to do when en = 0, and infers a latch 128 | ```verilog 129 | always @(d or q) 130 | begin 131 | if (en) q = d; // Condition missing for en = 0; previous value 132 | // will be held through latch 133 | end 134 | ``` 135 | Similarly, in the following case, if default case is missing in case statement and we don't have coverage for all possible cases, a latch is inferred. 136 | ```verilog 137 | always @(d or q) 138 | begin 139 | case (d) 140 | 2'b00: q = 0; 141 | 2'b01: q = 1; 142 | 2'b10: q = 1; // default condition missing; latch will be 143 | // inferred for condition d = 2'b11 to hold the 144 | // previous value 145 | endcase 146 | end 147 | ``` 148 | 149 | ***Note: Latches are only generated by combinational always blocks, the sequential always block will never generate a latch.*** 150 | 151 | 152 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 153 | 154 | # Basic hardware components 155 | 156 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 157 | 158 | ## Adders 159 | 160 | ### Half adder 161 | 162 | The half adder circuit is realized as shown in Figure 1. The block has two inputs ***a*** & ***b***, and two outputs ***sum*** and ***cout*** 163 | 164 | ![half_adder](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/half_adder.png) 165 | 166 | The same can be written in verilog as - 167 | 168 | ```verilog 169 | module half_adder (input a, b, 170 | output sum, cout); 171 | assign sum = a ^ b; 172 | assign cout = a & b; 173 | endmodule 174 | ``` 175 | 176 | ```verilog 177 | module full_adder (input a, b, 178 | output sum, cout); 179 | assign {cout, sum} = a + b; 180 | endmodule 181 | ``` 182 | 183 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 184 | 185 | ### Full adder 186 | 187 | The half adder circuit is realized as shown in Figure 1. The block has two inputs ***a***, ***b*** & ***cin***, and two outputs ***sum*** and ***cout*** 188 | 189 | ![full_adder](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/full_adder.png) 190 | 191 | The same can be written in verilog in many different ways- 192 | 193 | ```verilog 194 | module full_adder (input a, b, cin, 195 | output sum, cout); 196 | wire x, y, z; 197 | assign x = a ^ b; 198 | assign sum = x ^ cin; 199 | assign y = a & b; 200 | assign z = x & cin; 201 | assign cout = y | z; 202 | endmodule 203 | ``` 204 | 205 | ```verilog 206 | module full_adder (input a, b, cin, 207 | output sum, cout); 208 | assign {cout, sum} = a + b + cin; 209 | endmodule 210 | ``` 211 | 212 | ```verilog 213 | module full_adder (input a, b, cin, 214 | output sum, cout); 215 | assign sum = a ^ b ^ cin; 216 | assign cout = (a & b) | ((a ^ b) & cin); 217 | endmodule 218 | ``` 219 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 220 | 221 | ## Shifter and Rotator 222 | 223 | ![shifter](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Shifter_Rotator/right_shifter.png) 224 | 225 | ![shifter_lr](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Shifter_Rotator/right_left_shifter.png) 226 | 227 | ![rotator](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Shifter_Rotator/right_rotator.png) 228 | 229 | ![rotator_lr](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Shifter_Rotator/right_left_rotator.png) 230 | 231 | ![rotator_shifter](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Shifter_Rotator/shifter_rotator.png) 232 | 233 | 234 | Additional information can be found at [Design alternatives for barrel shifters](https://www.princeton.edu/~rblee/ELE572Papers/Fall04Readings/Shifter_Schulte.pdf) 235 | 236 | [![go_back](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_go_back.png)](#contents) 237 | 238 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 239 | 240 | ## Multiplier 241 | 242 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 243 | 244 | ## Divider 245 | 246 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 247 | ## Sorting network 248 | 249 | Sorting is a very important task generally performed through software, however, in hing sorting demand operations such as artificial intelligence and databases it becomes a necessity to implement sorting through hardware to speedup the process. This is implemented in hardware through a basic building block called ***compare and swap (CAS)*** block. The CAS block is connected in a certain way called bitonic network to sort the given set of numbers. 250 | 251 | ![sorting_networks_cas_blocks](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sorting_Network/cas_block.png) 252 | 253 | Figure 1: Compare and Swap Block 254 | 255 | The CAS block has two inputs, ***A*** and ***B*** and has two outputs ***O1 = max(A,B)*** and ***O2 = min(A,B)***. A CAS block is made up of an n-bit comparator, two n-bit multiplexers to select from inputs A and B where n-bit is the data width of A and B. There can be two configurations of the CAS block to sort the numbers in an ascending or descending order. 256 | 257 | To differentiate between the ascending and decending order CAS blocks, we use arrows to depict the type of sort. The arrow-head indicates port with ***max*** output and the arrow-root indicates the port with the ***min*** output. 258 | 259 | ```verilog 260 | module comapre_and_swap(input [3:0] data1, data2, 261 | output [3:0] max, min); 262 | 263 | // Comparator output declaration 264 | wire data1_greater_than_data2; 265 | 266 | // Comparator output = 1 if data1 > data2 267 | // Comparator output = 0 if data1 <= data2 268 | assign data1_greater_than_data2 = data1 > data2; 269 | 270 | // max data 271 | assign max = (data1_greater_than_data2 == 1'b1) ? data1 : data2; 272 | 273 | // min data 274 | assign min = (data1_greater_than_data2 == 1'b1) ? data2 : data1; 275 | 276 | endmodule 277 | ``` 278 | 279 | ![sorting_networks_components](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sorting_Network/sorting_network_blocks.png) 280 | 281 | Figuren 2: Ascending and descending CAS blocks 282 | 283 | ### Bitonic Sorting Networks 284 | 285 | A sorting network is a combination of CAS blocks, where each CAS block takes two inputs and swaps it if required, based on its ascending or descending configuration. ***Bitonic sorting networks*** uses the procedure of ***bitonic merge (BM)***, given two equal size sets of input data, sorted in opposing directions, the BM procedure will create a combined set of sorted data. It recursively merges an ascending and a descending set of size N /2 to make a sorted set of size N. Figure 3 and Figure 4 shows the CAS network for a 4-input and 8-input bitonic sorting network made up of ascending and descending BM units. 286 | 287 | The total number of CAS blocks in any N-input bitonic sorting is N × log2 ( N ) × (log2( N ) + 1)/4. The following table shows the CAS blocks needed for N-input bitonic networks. 288 | 289 | | Input data numbers | 8 | 16 | 32 | 256 | 290 | | ------------------ | -- | -- | -- | --- | 291 | | CAS blocks needed in sorting network | 24 | 80 | 240 | 4608 | 292 | 293 | ![sorting_networks_4nos](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sorting_Network/sorting_network_4nos.png) 294 | 295 | Figure 3: Sorting 4 numbers using CAS blocks in ascending and descending order 296 | 297 | ![sorting_networks_8nos](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sorting_Network/sorting_network_8nos.png) 298 | 299 | Figure 4: Sorting 8 numbers using CAS blocks in ascending order 300 | 301 | ```verilog 302 | module sort_network_8x4 (input [3:0] data_in [0:7], 303 | output [3:0] data_sort [0:7]); 304 | 305 | // wire declarations for all the sorting intermediaries 306 | wire [3:0] stage1 [0:7]; 307 | 308 | wire [3:0] stage2_0 [0:7]; 309 | wire [3:0] stage2_1 [0:7]; 310 | 311 | wire [3:0] stage3_0 [0:7]; 312 | wire [3:0] stage3_1 [0:7]; 313 | wire [3:0] stage3_2 [0:7]; 314 | 315 | 316 | //------------------------------------------------------------------------ 317 | // Stage 0 has only one level of sorting 318 | //------------------------------------------------------------------------ 319 | comapre_and_swap u1 (data_in[0], data_in[1], stage1[1], stage1[0]); 320 | comapre_and_swap u2 (data_in[2], data_in[3], stage1[2], stage1[3]); 321 | comapre_and_swap u3 (data_in[4], data_in[5], stage1[5], stage1[4]); 322 | comapre_and_swap u4 (data_in[6], data_in[7], stage1[6], stage1[7]); 323 | 324 | //------------------------------------------------------------------------ 325 | //Stage 1 has 2 levels of sorting 326 | //------------------------------------------------------------------------ 327 | comapre_and_swap u5 (stage1[0], stage1[2], stage2_0[2], stage2_0[0]); 328 | comapre_and_swap u6 (stage1[1], stage1[3], stage2_0[3], stage2_0[1]); 329 | comapre_and_swap u7 (stage1[4], stage1[6], stage2_0[4], stage2_0[6]); 330 | comapre_and_swap u8 (stage1[5], stage1[7], stage2_0[5], stage2_0[7]); 331 | 332 | comapre_and_swap u9 (stage2_0[0], stage2_0[2], stage2_1[2], stage2_1[0]); 333 | comapre_and_swap u10 (stage2_0[1], stage2_0[3], stage2_1[3], stage2_1[1]); 334 | comapre_and_swap u11 (stage2_0[4], stage2_0[6], stage2_1[4], stage2_1[6]); 335 | comapre_and_swap u12 (stage2_0[5], stage2_0[7], stage2_1[5], stage2_1[7]); 336 | 337 | //------------------------------------------------------------------------ 338 | // Stage 2 has 3 levels of sorting 339 | //------------------------------------------------------------------------ 340 | comapre_and_swap u13 (stage2_1[0], stage2_1[4], stage3_0[4], stage3_0[0]); 341 | comapre_and_swap u14 (stage2_1[1], stage2_1[5], stage3_0[5], stage3_0[1]); 342 | comapre_and_swap u15 (stage2_1[2], stage2_1[6], stage3_0[6], stage3_0[2]); 343 | comapre_and_swap u16 (stage2_1[3], stage2_1[7], stage3_0[7], stage3_0[3]); 344 | 345 | comapre_and_swap u17 (stage3_0[0], stage3_0[2], stage3_1[2], stage3_1[0]); 346 | comapre_and_swap u18 (stage3_0[1], stage3_0[3], stage3_1[3], stage3_1[1]); 347 | comapre_and_swap u19 (stage3_0[4], stage3_0[6], stage3_1[6], stage3_1[4]); 348 | comapre_and_swap u20 (stage3_0[5], stage3_0[7], stage3_1[7], stage3_1[5]); 349 | 350 | comapre_and_swap u21 (stage3_1[0], stage3_1[1], stage3_2[1], stage3_2[0]); 351 | comapre_and_swap u22 (stage3_1[2], stage3_1[3], stage3_2[3], stage3_2[2]); 352 | comapre_and_swap u23 (stage3_1[4], stage3_1[5], stage3_2[5], stage3_2[4]); 353 | comapre_and_swap u24 (stage3_1[6], stage3_1[7], stage3_2[7], stage3_2[6]); 354 | 355 | // Sorted data is assigned to output 356 | assign data_sort = stage3_2; 357 | 358 | endmodule 359 | ``` 360 | 361 | [![Run on EDA](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_run-on-eda-playground.png)](https://www.edaplayground.com/x/9JEa) 362 | 363 | The information found here was referred from an outstanding paper [Low-Cost Sorting Network Circuits Using Unary Processing](https://ieeexplore.ieee.org/document/8338366) 364 | 365 | Additional information about sorting networks can be found [here](http://staff.ustc.edu.cn/~csli/graduate/algorithms/book6/chap28.htm) and [here](http://www.cs.kent.edu/~batcher/sort.pdf) 366 | 367 | [![go_back](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_go_back.png)](#contents) 368 | 369 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 370 | 371 | ## D flip flop 372 | 373 | ![dff](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/dff.png) 374 | 375 | Verilog code for D flip-flop with active-high synchronous reset - 376 | 377 | ```verilog 378 | module dff (input d, clk, srst, 379 | output reg Q); 380 | always @ (posedge clk) begin 381 | if (srst) 382 | Q <= 1'b0; 383 | else 384 | Q <= d; 385 | end 386 | endmodule 387 | ``` 388 | 389 | 390 | Verilog code for D flip-flop with active-low asynchronous reset - 391 | 392 | ```verilog 393 | module dff (input D, clk, arst, 394 | output reg Q); 395 | always @ (posedge clk or negedge arst) begin 396 | if (~arst) 397 | Q <= 1'b0; 398 | else 399 | Q <= D; 400 | end 401 | endmodule 402 | ``` 403 | 404 | 405 | Verilog code for D flip-flop with active-low asynchronous reset - 406 | 407 | ```verilog 408 | module dff (input D, clk, arst, srst 409 | output reg Q); 410 | always @ (posedge clk or negedge arst) begin 411 | if (~arst) 412 | Q <= 1'b0; 413 | else if (srst) 414 | Q <= 1'b0; 415 | else 416 | Q <= D; 417 | end 418 | endmodule 419 | ``` 420 | 421 | [![go_back](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_go_back.png)](#contents) 422 | 423 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 424 | 425 | ## Serial in parallel out (SIPO) 426 | 427 | Typically in a Serial in Parallel out circuit, there are as many flops as the size of the parallel out. The input data is shifted in with clk and when all the data bits are available, the serially loaded data is read through the parallel port. 428 | 429 | Here, say we have 8-bit parallel port, so it takes 8 clk cycles to serially load 8-bits of data and the data is available for 1 clock cycle and then new data starts coming in resulting in the output being stable for only 1 clock cycle. 430 | 431 | ![sipo_basic](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/SIPO/sipo_basic.png) 432 | 433 | Figure 1: Basic serial-in-parallel-out circuit 434 | 435 | ```verilog 436 | module sipo_1 (input load, clk, rst, 437 | input data_in, 438 | output [7:0] data_out); 439 | 440 | // SIPO register array to read and shift data 441 | reg [7:0] data_reg; 442 | 443 | always @ (posedge clk or negedge rst) begin 444 | if (~rst) 445 | data_reg <= 8'h00; // Reset SIPO register on reset 446 | else if (load) 447 | data_reg <= {data_in, data_reg[7:1]}; // Load data to the SIPO register by right shifts 448 | end 449 | 450 | // Assign the SIPO register data to data_out wires 451 | assign data_out = data_reg; 452 | 453 | endmodule 454 | ``` 455 | 456 | If there is a need to keep the output data stable until we have the next valid data, we need to use a 2-step architecture as shown below. The data is clocked in to the serial registers at the serial_clk then when valid data is loaded, the serial_clk and parallel_clk are asserted together. This way the data loaded into the output registers stay constant until the next valid data is loaded serially. 457 | 458 | ![sipo_capture_reg](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/SIPO/sipo_capture_reg.png) 459 | 460 | Figure 2: Serial-in-parallel-out circuit with capture register 461 | 462 | ```verilog 463 | module sipo_2 (input load, clk, rst, 464 | input data_in, 465 | output reg [7:0] data_out); 466 | 467 | // SIPO register array to read and shift data 468 | reg [7:0] data_reg; 469 | 470 | always @ (posedge clk or negedge rst) begin 471 | if (~rst) begin 472 | data_reg <= 8'h00; // Reset SIPO register on reset 473 | data_out <= 8'h00; // Reset capture register 474 | end 475 | else begin 476 | if (load) 477 | data_reg <= {data_in, data_reg[7:1]}; // Load data to the SIPO register by right shifts 478 | else 479 | data_out <= data_reg; // Assign SIPO register data to capture register 480 | end 481 | end 482 | 483 | endmodule 484 | ``` 485 | 486 | [![go_back](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_go_back.png)](#contents) 487 | 488 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 489 | 490 | ## Parallel in serial out (PISO) 491 | 492 | Parallel-in serial-out is a one of the basic elements of ***serializer-deserializer (SerDes) circuits***. The PISO allows the parallel loading of data following which the data can be shifted out serially from either the MSB or the LSB side. This is how a parallel to serial conversion takes place. 493 | 494 | ![piso_block](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/PISO/piso_block.png) 495 | 496 | To load the data we need as many flip-flops as the data width of the parallel loading, i.e., if the data width is 8 bits, we need 8 flip flops to store these 8 bits. To differentiate between a load or shift operation we need an additional input which can be multiplexed for indicating either shift and load. If the signal is 1 it indicates a load and if 0 a shift. 497 | 498 | ![piso_basic](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/PISO/piso.png) 499 | 500 | The loading can be be asynchronous needing a flip-flop with set/reset pins. However, here we will be looking at a circuit with synchronous loading and shifting of 4-bit data 501 | 502 | ```verilog 503 | module piso (input load, clk, rst, 504 | input [7:0] data_in, 505 | output reg data_out); 506 | 507 | // PISO register array to load and shift data 508 | reg [7:0] data_reg; 509 | 510 | always @ (posedge clk or negedge rst) begin 511 | if (~rst) 512 | data_reg <= 8'h00; // Reset PISO register array on reset 513 | else begin 514 | 515 | // Load the data to the PISO register array and reset the serial data out register 516 | if (load) 517 | {data_reg, data_out} <= {data_in, 1'b0}; 518 | // Shift the loaded data 1 bit right; into the serial data out register 519 | else 520 | {data_reg, data_out} <= {1'b0, data_reg[7:0]}; 521 | end 522 | end 523 | 524 | endmodule 525 | ``` 526 | 527 | [![go_back](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_go_back.png)](#contents) 528 | 529 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 530 | 531 | ## Counters 532 | 533 | ### Synchronous counter 534 | 535 | ### Asynchronous/Ripple counter 536 | 537 | ### Ring counter 538 | 539 | ### Johnson counter 540 | 541 | ### Sequence counter 542 | 543 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 544 | 545 | ## MOD-N Counters 546 | 547 | ### MOD-3 counter 548 | 549 | ### MOD-5 counter 550 | 551 | ### MOD-6 counter 552 | 553 | ### MOD-7 counter 554 | 555 | ### MOD-8 counter 556 | 557 | ### MOD-9 counter 558 | 559 | ### MOD-11 counter 560 | 561 | ### MOD-12 counter 562 | 563 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 564 | 565 | ## Gray counter 566 | 567 | The gray code is a type of binary number ordering such that each number differes from its previous and the following number by exactly 1-bit. Gray codes are used in cases when the binary numbers transmitted by a digital system may result in a fault or ambuiguity or for implementing error corrections. 568 | 569 | The most simple implementation of a gray code counter will be a binary counter followed by a ***binary to gray*** converter. However, the datapath is huge resulting in a very low clock frequency. This is a good motive to pursue a design to implement a gray counter with a smaller datapath. 570 | 571 | ![gray_counter_circuit](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Gray_Counter/gray_counter_basic.png) 572 | 573 | Consider a 4-bit gray code `gray[3:0]` in the following table. 574 | 575 | ![gray_code_table](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Gray_Counter/gray_code_table.png) 576 | 577 | The ***count*** column gives the decimal value for the corrseponding gray code, ***gray[3:0]*** represent the binary encoded gray code, and ***gray[-1]*** is a place-holder and used to actually implement the gray code counter. 578 | 579 | From the table the following observations can be made - 580 | 1. ***gray[-1]*** flips every clock cycle, and is preset to `1'b1` 581 | 2. ***gray[0]*** flips everytime `gray[-1] == 1` 582 | 3. ***gray[1]*** flips everytime `(gray[0] == 1) & (gray[-1] == 0)` 583 | 4. ***gray[2]*** flips everytime `(gray[1] == 1) & (gray[0] == 0) & (gray[-1] == 0)` 584 | 5. ***gray[3]*** flips twice for a cycle which means we need additional condition to account for this. It flips when and `(gray[3] == 1) or (gray[2] == 0)` and `(gray[1] == 0) & (gray[0] == 0) & (gray[-1] == 0)` 585 | 586 | The ***red arrow*** in the table shows the bit getting flipped and the highlighed bits show the condition for the flip. 587 | 588 | The same has been shown here in the following circuit. ***gray[3:-1]*** is represented by the flip-flops and the logic when these flip make up the combinational logic. 589 | 590 | ![gray_counter_circuit1](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Gray_Counter/gray_counter.png) 591 | 592 | ```verilog 593 | module gray_counter(input clk, rst, 594 | output [3:0] gray_count); 595 | 596 | // D flip flops to store the gray count and the placeholder value 597 | reg [3:-1] q; 598 | 599 | // register declaration for combinational logic 600 | reg all_zeros_below[2:-1]; 601 | 602 | // Combinational logic to compute if the value below any bit of the gray count is 0 603 | always @ (*) begin 604 | all_zeros_below[-1] = 1; 605 | for (integer i = 0; i<3; i= i+1) begin 606 | all_zeros_below[i] = all_zeros_below[i-1] & ~q[i-1]; 607 | end 608 | end 609 | 610 | always @ (posedge clk) begin 611 | if (rst) q[3:-1] <= 5'b0000_1; 612 | 613 | else begin 614 | // The placegolder value toggles every clock 615 | q[-1] <= ~q[-1]; 616 | 617 | // The bits [n-1:0] toggle everytime the sequence below it is 1 followed by all zeros (1000...) 618 | for (integer i = 0; i<3; i= i+1) begin 619 | q[i] <= (q[i-1] & all_zeros_below[i-1]) ? ~q[i] : q[i]; 620 | end 621 | 622 | // The MSB flips when either the nth/(n-1)th bit is 1 followed by all zeros (X1000... or 1X000...) 623 | q[3] <= ((q[3] | q[2]) & all_zeros_below[2]) ? ~q[3] : q[3]; 624 | end 625 | end 626 | 627 | // The flip flop value is connected to the gray counter output. 628 | assign gray_count = q[3:0]; 629 | 630 | endmodule 631 | ``` 632 | 633 | [![Run on EDA](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_run-on-eda-playground.png)](https://www.edaplayground.com/x/Q6Zk) 634 | 635 | ![gray_counter_wave](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Gray_Counter/gray_counter_wave.png) 636 | 637 | [![go_back](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_go_back.png)](#contents) 638 | 639 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 640 | 641 | ## Fibonacci counter 642 | 643 | The Fibonacci numbers together form a fibonacci sequence, `F(n)`, such that each number is the sum of the two preceding ones, starting from 0 and 1 644 | 645 | i.e., `F(0) = 0`, `F(1) = 1` 646 | 647 | and `F(n) = F(n-1) + F(n-1)` for all `n > 2` 648 | 649 | The Fibonacci sequence thus becomes, `0, 1, 1, 2, 3, 5, 8, 13, 21, ....` 650 | 651 | The fibonacci numbers are used in various [computational applications](https://www.quora.com/What-are-the-practical-applications-of-Fibonacci-other-than-used-to-teach-programming) involving hardware: 652 | - Pseudorandom number generators 653 | - Determining the greatest common divisor 654 | - A one-dimensional optimization method, called the Fibonacci search technique 655 | - The Fibonacci number series is used for optional lossy compression 656 | 657 | Instead of performing the fibonacci computation using software which consumes a lot of time it is easier to faster to implement the fibonacci counter in hardware. 658 | 659 | Fibonacci Counter can be implemented in hardware with two registers A and B to store the initial numbers in the series, i.e., A = 1 and B = 0. The sum of the both A and B can be stored in A and the value in A can be moved into B and register B is used as the output. However, in the 2 register format, after reset we don't see the initial sequence number '0'. This can be resolved by adding a register C in series. The same is shown in the following waveform and schematic. 660 | 661 | ![fibonacci_counter](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Fibonacci/fibonacci_counter.png) 662 | 663 | The same can be implemented in verilog as - 664 | 665 | ```verilog 666 | module fibC (input clk, rst, 667 | output [3:0] out); 668 | 669 | // Registers to store the current and previous values of the fibonacci counter 670 | reg [3:0] RegA, RegB, RegC; 671 | 672 | always @ (posedge clk) begin 673 | if (rst) begin 674 | RegA <= 4'h1; // Start RegA with the second value of fibonacci series - '1' 675 | RegB <= 4'h0; // Start RegB with the first value of fibonacci series - '0' 676 | RegC <= 4'h0; // Reset RegC to '0' 677 | end 678 | else begin 679 | RegA <= RegB[3] ? 4'h1 : RegA + RegB; // if RegB == 8, reset RegA 680 | RegB <= RegB[3] ? 4'h0 : RegA; // if RegB == 8, reset RegB 681 | RegC <= RegB; // RegC is a synchronization register 682 | end 683 | end 684 | 685 | // Only one of the following two lines should be uncommented 686 | 687 | assign out = RegB; // To ignore the '0' at the startup after reset, uncomment this line 688 | //assign out = RegC; // To start with a '0' at startup after reset, uncomment this line 689 | 690 | endmodule 691 | ``` 692 | 693 | [![Run on EDA](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_run-on-eda-playground.png)](https://www.edaplayground.com/x/An9k) 694 | 695 | ![fib_counter_wave](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Fibonacci_Counter/gray_counter_wave.png) 696 | 697 | [![go_back](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_go_back.png)](#contents) 698 | 699 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 700 | 701 | ## Frequency Dividers 702 | 703 | Frequency divider is any curcuit that divides the frequency of the input signal, say `f` by a factor `n`, such that the frequency of the output signal is `f/n`. The frequency dividers with uneven pulse widths are very simple to be implemented with the use of counters and mod-n counters discussed earlier. However, we need additional circuitry to create a frequency divider with ***50% duty cycle***. 704 | 705 | Here, all the following frequency dividers have integer dividers `n = 1,2,3,4,5....` and have a ***50% duty cycle***. 706 | 707 | [![Run on EDA](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_run-on-eda-playground.png)](https://www.edaplayground.com/x/DMiK) 708 | 709 | ### Divide by 2 710 | 711 | The most basic a 1-bit counter also doubles up as a divide-by-2 circuit since for any given clock frequency, the output of the 1 bit counter is 1/2 the frequency of the cock signal. 712 | 713 | ![div_by_2](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Frequency_Dividers/div_by_2.png) 714 | 715 | The same can be modelled in verilog as: 716 | 717 | ```verilog 718 | module div_by_2 (input clk, rst, 719 | output clk_out); 720 | 721 | // Register to store the current count value 722 | reg Q; 723 | 724 | // State memory 725 | always @ (posedge clk) begin 726 | if (rst) 727 | Q <= 1'b0; // If reset, set Q to 0 728 | else 729 | Q <= ~Q; // If not reset, set Q to the next count value 730 | end 731 | 732 | // The clk/2 is set when Q == 1 733 | assign clk_out = Q; 734 | 735 | endmodule 736 | ``` 737 | 738 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 739 | 740 | ### Divide by 3 741 | 742 | To implement a divide by 3, we need to count to 3 and so we will need two flip-flops to count states `2'b00, 2'b01, 2'b10`. However since dividing factor is not equal to `2^n` we need additional flip-flops to get a 50% duty-cycle. We can achieve this by shifting the state ***Q[0]*** by 1/2 clock cycle and then ***OR***ing with ***Q[1]***. The 1/2 clock cycle shift is made by using a negative edge-triggered flip-flop. 743 | 744 | ![div_by_3_waveform](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Frequency_Dividers/div_by_3_waveform.png) 745 | 746 | Here, tp stands for ***time period of the clock***, i.e. ***+ 0.5 tp*** stands for the signal delayed by 0.5 clock period. 747 | 748 | The same can be modelled in verilog as: 749 | 750 | ```verilog 751 | module div_by_3 (input clk, rst, 752 | output clk_out); 753 | 754 | // Registers to store the current count value and wire to compute the next count value 755 | reg [1:0] Q, Q_next; 756 | 757 | // Register to delay Q[0] signal by 0.5 clock period 758 | reg Q_delay_0_5tp; 759 | 760 | // Combinational logic to compute the next state logic (count value) 761 | always @ (*) begin 762 | case(Q) 763 | 2'b00: Q_next = 2'b01; 764 | 2'b01: Q_next = 2'b10; 765 | 2'b10: Q_next = 2'b00; 766 | default: Q_next = 2'b00; 767 | endcase 768 | end 769 | 770 | // State memory 771 | always @ (posedge clk) begin 772 | if (rst) 773 | Q <= 2'h0; // If reset, set Q to 0 774 | else 775 | Q <= Q_next; // If not reset, set Q to the next count value 776 | end 777 | 778 | // Always block to delay Q[0] by 0.5 clock cycle 779 | always @ (negedge clk) begin 780 | if (rst) 781 | Q_delay_0_5tp <= 1'b0; 782 | else 783 | Q_delay_0_5tp <= Q[0]; 784 | end 785 | 786 | // The clk/3 is set when Q[0]_delayed_by_0.5_cycle == 1 or Q[1] == 1 787 | assign clk_out = Q_delay_0_5tp | Q[1]; 788 | 789 | endmodule 790 | ``` 791 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 792 | 793 | ### Divide by 4 794 | 795 | To implement a divide by 4, we need to count to 4 and so we will need two flip-flops to count states `2'b00, 2'b01, 2'b10, 2'b10`. We can use the state Q[1] as the output which has the frequency `fclk/4`. 796 | 797 | ![div_by_4](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Frequency_Dividers/div_by_4_waveform.png) 798 | 799 | ```verilog 800 | module div_by_4 (input clk, rst, 801 | output clk_out); 802 | 803 | // Registers to store the current count value and wire to compute the next count value 804 | reg [1:0] Q, Q_next; 805 | 806 | // Combinational logic to compute the next state logic (count value) 807 | always @ (*) begin 808 | case(Q) 809 | 2'b00: Q_next = 2'b01; 810 | 2'b01: Q_next = 2'b10; 811 | 2'b10: Q_next = 2'b11; 812 | 2'b11: Q_next = 2'b00; 813 | default: Q_next = 2'b00; 814 | endcase 815 | end 816 | 817 | // State memory 818 | always @ (posedge clk) begin 819 | if (rst) 820 | Q <= 2'h0; // If reset, set Q to 0 821 | else 822 | Q <= Q_next; // If not reset, set Q to the next count value 823 | end 824 | 825 | // The clk/4 is set when Q[1] == 1 826 | assign clk_out = Q[1]; 827 | 828 | endmodule 829 | ``` 830 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 831 | 832 | ### Divide by 5 833 | 834 | To implement a divide by 5, we need to count to 3 and so we will need 3 flip-flops to count states `2'b000, 2'b001, 2'b010, 2'b011, 2'b100`. However since dividing factor is not equal to `2^n` we need additional flip-flops to get a 50% duty-cycle. We can achieve this by shifting the state ***Q[1]*** by 1/2 clock cycle and then ***OR***ing with ***Q[2]***. The 1/2 clock cycle shift is made by using a negative edge-triggered flip-flop. 835 | 836 | ![div_by_5_table](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Frequency_Dividers/div_by_5_table.png) 837 | 838 | The table shows the current counter state and the next state. The first column shows the clock divider output. It must be noted the `0/1` and `1/0` refers to the signal changing from `0 -> 1` and `1 -> 0` respectively at the falling edge of the clock. 839 | 840 | ![div_by_5_waveform](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Frequency_Dividers/div_by_5_waveform.png) 841 | 842 | Here, tp stands for ***time period of the clock***, i.e. ***+ 0.5 tp*** stands for the signal delayed by 0.5 clock period. 843 | 844 | The same can be modelled in verilog as: 845 | 846 | ```verilog 847 | module div_by_5 (input clk, rst, 848 | output clk_out); 849 | 850 | // Registers to store the current count value and wire to compute the next count value 851 | reg [2:0] Q, Q_next; 852 | 853 | // Register to delay Q[1] signal by 0.5 clock period 854 | reg Q_delay_0_5tp; 855 | 856 | // Combinational logic to compute the next state logic (count value) 857 | always @ (*) begin 858 | if (Q == 3'd4) 859 | Q_next = 3'h0; // If counted to 4, set Q to 0 860 | else 861 | Q_next = Q + 1; // If not counted to 4, set Q to Q + 1 862 | end 863 | 864 | // State memory 865 | always @ (posedge clk) begin 866 | if (rst) 867 | Q <= 3'h0; // If reset, set Q to 0 868 | else 869 | Q <= Q_next; // If not reset, set Q to the next count value 870 | end 871 | 872 | // Always block to delay Q[1] by 0.5 clock cycle 873 | always @ (negedge clk) begin 874 | if (rst) 875 | Q_delay_0_5tp <= 1'b0; 876 | else 877 | Q_delay_0_5tp <= Q[1]; 878 | end 879 | 880 | // The clk/5 is set when Q[1]_delayed_by_0.5_cycle == 1 or Q[2] == 1 881 | assign clk_out = Q_delay_0_5tp | Q[2]; 882 | 883 | endmodule 884 | ``` 885 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 886 | 887 | ### Divide by 6 888 | 889 | To implement a divide by 6, we need to count to 6 and so we will need 3 flip-flops to count states `2'b000, 2'b001, 2'b010, 2'b011, 2'b100, 2'b101`. However since dividing factor is not equal to `2^n` we need additional flip-flops to get a 50% duty-cycle. We can achieve this by shifting the state ***Q[1]*** by 1 clock cycle and then ***OR***ing with ***Q[2]***. The 1 clock cycle shift is made by using a positive edge-triggered flip-flop. 890 | 891 | ![div_by_6_table](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Frequency_Dividers/div_by_6_table.png) 892 | 893 | The table shows the current counter state and the next state. The first column shows the clock divider output. 894 | 895 | ![div_by_6_waveform](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Frequency_Dividers/div_by_6_waveform.png) 896 | 897 | Here, tp stands for ***time period of the clock***, i.e. ***+ 1 tp*** stands for the signal delayed by 1 clock period. 898 | 899 | The same can be modelled in verilog as: 900 | 901 | ```verilog 902 | module div_by_6 (input clk, rst, 903 | output clk_out); 904 | 905 | // Registers to store the current count value and wire to compute the next count value 906 | reg [2:0] Q, Q_next; 907 | 908 | // Registers to delay Q[1] signal by 1 clock period 909 | reg Q_delay_1tp; 910 | 911 | 912 | // Combinational logic to compute the next state logic (count value) 913 | always @ (*) begin 914 | if (Q == 3'd5) 915 | Q_next = 3'h0; // If counted to 5, set Q to 0 916 | else 917 | Q_next = Q + 1; // If not counted to 5, set Q to Q + 1 918 | end 919 | 920 | // State memory 921 | always @ (posedge clk) begin 922 | if (rst) 923 | Q <= 3'h0; // If reset, set Q to 0 924 | else 925 | Q <= Q_next; // If not reset, set Q to the next count value 926 | end 927 | 928 | // Always block to delay Q[1] by 1 clock cycle 929 | always @ (posedge clk) begin 930 | if (rst) begin 931 | Q_delay_1tp <= 1'b0; 932 | end 933 | else begin 934 | Q_delay_1tp <= Q[1]; 935 | end 936 | end 937 | 938 | // The clk/6 is set when Q[1]_delayed_by_1_cycle == 1 or Q[2] == 1 939 | assign clk_out = Q_delay_1tp | Q[2]; 940 | 941 | endmodule 942 | ``` 943 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 944 | 945 | ### Divide by 9 946 | 947 | To implement a divide by 9, we need to count upto 9 and so we will need two flip-flops to count states `4'b0000, 4'b0001, .... 4'b0111, 4'b1000`. However since dividing factor is not equal to `2^n` we need additional flip-flops to get a 50% duty-cycle. We can achieve this by shifting the state ***Q[2]*** by 1/2 clock cycle and then ***OR***ing with ***Q[3]***. The 1/2 clock cycle shift is made by using a negative edge-triggered flip-flop. 948 | 949 | ![div_by_9_table](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Frequency_Dividers/div_by_9_table.png) 950 | 951 | The table shows the current counter state and the next state. The first column shows the clock divider output. It must be noted the `0/1` and `1/0` refers to the signal changing from `0 -> 1` and `1 -> 0` respectively at the falling edge of the clock. All other values change at the rising edge of the clock. 952 | 953 | ![div_by_9_waveform](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Frequency_Dividers/div_by_9_waveform.png) 954 | 955 | Here, tp stands for ***time period of the clock***, i.e. ***+ 0.5 tp*** stands for the signal delayed by 0.5 clock period. 956 | 957 | The same can be modelled in verilog as: 958 | 959 | ```verilog 960 | module div_by_9 (input clk, rst, 961 | output clk_out); 962 | 963 | // Registers to store the current count value and wire to compute the next count value 964 | reg [3:0] Q, Q_next; 965 | 966 | // Register to delay Q[2] signal by 0.5 clock period 967 | reg Q_delay_0_5tp; 968 | 969 | // Combinational logic to compute the next state logic (count value) 970 | always @ (*) begin 971 | if (Q == 4'd8) 972 | Q_next = 4'h0; // If counted to 8, set Q to 0 973 | else 974 | Q_next = Q + 1; // If not counted to 8, set Q to Q + 1 975 | end 976 | 977 | // State memory 978 | always @ (posedge clk) begin 979 | if (rst) 980 | Q <= 4'h0; // If reset, set Q to 0 981 | else 982 | Q <= Q_next; // If not reset, set Q to the next count value 983 | end 984 | 985 | 986 | // Always block to delay Q[2] by 1.5 clock cycle 987 | always @ (negedge clk) begin 988 | if (rst) 989 | Q_delay_0_5tp <= 1'b0; 990 | else 991 | Q_delay_0_5tp <= Q[2]; 992 | end 993 | 994 | // The clk/9 is set when Q[2]_delayed_by_0.5_cycle == 1 or Q[3] == 1 995 | assign clk_out = Q_delay_0_5tp | Q[3]; 996 | 997 | endmodule 998 | ``` 999 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1000 | 1001 | ### Divide by 11 1002 | 1003 | To implement a divide by 11, we need to count upto 11 and so we will need two flip-flops to count states `4'b0000, 4'b0001, .... 4'b1001, 4'b1010`. However since dividing factor is not equal to `2^n` we need additional flip-flops to get a 50% duty-cycle. We can achieve this by shifting the state ***Q[2]*** by 1.5 clock cycles and then ***OR***ing with ***Q[3]***. The 1.5 clock cycle shift is made by using a positive edge-triggered flip flop followed by a negative edge-triggered flip-flop. 1004 | 1005 | ![div_by_11_table](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Frequency_Dividers/div_by_11_table.png) 1006 | 1007 | The table shows the current counter state and the next state. The first column shows the clock divider output. It must be noted the `0/1` and `1/0` refers to the signal changing from `0 -> 1` and `1 -> 0` respectively at the falling edge of the clock. All other values change at the rising edge of the clock. 1008 | 1009 | ![div_by_11_waveform](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Frequency_Dividers/div_by_11_waveform.png) 1010 | 1011 | Here, tp stands for ***time period of the clock***, i.e. ***+ 1.5 tp*** stands for the signal delayed by 1.5 clock periods. 1012 | 1013 | The same can be modelled in verilog as: 1014 | 1015 | ```verilog 1016 | module div_by_11 (input clk, rst, 1017 | output clk_out); 1018 | 1019 | // Registers to store the current count value and wire to compute the next count value 1020 | reg [3:0] Q, Q_next; 1021 | 1022 | // Register to delay Q[2] signal by 1 clock period 1023 | reg Q_delay_1tp; 1024 | 1025 | // Register to delay Q[2] signal by 1.5 clock period 1026 | reg Q_delay_1_5tp; 1027 | 1028 | // Combinational logic to compute the next state logic (count value) 1029 | always @ (*) begin 1030 | if (Q == 4'd10) 1031 | Q_next = 4'h0; // If counted to 10, set Q to 0 1032 | else 1033 | Q_next = Q + 1; // If not counted to 10, set Q to Q + 1 1034 | end 1035 | 1036 | // State memory 1037 | always @ (posedge clk) begin 1038 | if (rst) 1039 | Q <= 4'h0; // If reset, set Q to 0 1040 | else 1041 | Q <= Q_next; // If not reset, set Q to the next count value 1042 | end 1043 | 1044 | // Always block to delay Q[2] by 1 clock cycle 1045 | always @ (posedge clk) begin 1046 | if (rst) 1047 | Q_delay_1tp <= 1'b0; 1048 | else 1049 | Q_delay_1tp <= Q[2]; 1050 | end 1051 | 1052 | // Always block to delay Q[2] by 1.5 clock cycle 1053 | always @ (negedge clk) begin 1054 | if (rst) 1055 | Q_delay_1_5tp <= 1'b0; 1056 | else 1057 | Q_delay_1_5tp <= Q_delay_1tp; 1058 | end 1059 | 1060 | // The clk/11 is set when Q[2]_delayed_by_1.5_cycle == 1 or Q[3] == 1 1061 | assign clk_out = Q_delay_1_5tp | Q[3]; 1062 | 1063 | endmodule 1064 | ``` 1065 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1066 | 1067 | ### Divide by 12 1068 | 1069 | To implement a divide by 12, we need to count upto 12 and so we will need two flip-flops to count states `4'b0000, 4'b0001, .... 4'b1010, 4'b1011`. However since dividing factor is not equal to `2^n` we need additional flip-flops to get a 50% duty-cycle. We can achieve this by shifting the state ***Q[2]*** by 2 clock cycles and then ***OR***ing with ***Q[3]***. The 1/2 clock cycle shift is made by using a 2 positive edge-triggered flip-flops in series. 1070 | 1071 | ![div_by_12_table](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Frequency_Dividers/div_by_12_table.png) 1072 | 1073 | The table shows the current counter state and the next state. The first column shows the clock divider output. 1074 | 1075 | ![div_by_12_waveform](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Frequency_Dividers/div_by_12_waveform.png) 1076 | 1077 | Here, tp stands for ***time period of the clock***, i.e. ***+ 2 tp*** stands for the signal delayed by 2 clock periods. 1078 | 1079 | The same can be modelled in verilog as: 1080 | 1081 | ```verilog 1082 | module div_by_12 (input clk, rst, 1083 | output clk_out); 1084 | 1085 | // Registers to store the current count value and wire to compute the next count value 1086 | reg [3:0] Q, Q_next; 1087 | 1088 | // Registers to delay Q[2] signal by 2 clock period 1089 | reg Q_delay_1tp, Q_delay_2tp; 1090 | 1091 | 1092 | // Combinational logic to compute the next state logic (count value) 1093 | always @ (*) begin 1094 | if (Q == 4'd11) 1095 | Q_next = 4'h0; // If counted to 11, set Q to 0 1096 | else 1097 | Q_next = Q + 1; // If not counted to 11, set Q to Q + 1 1098 | end 1099 | 1100 | // State memory 1101 | always @ (posedge clk) begin 1102 | if (rst) 1103 | Q <= 4'h0; // If reset, set Q to 0 1104 | else 1105 | Q <= Q_next; // If not reset, set Q to the next count value 1106 | end 1107 | 1108 | // Always block to delay Q[2] by 2 clock cycle 1109 | always @ (posedge clk) begin 1110 | if (rst) begin 1111 | Q_delay_1tp <= 1'b0; 1112 | Q_delay_2tp <= 1'b0; 1113 | end 1114 | else begin 1115 | Q_delay_1tp <= Q[2]; 1116 | Q_delay_2tp <= Q_delay_1tp; 1117 | end 1118 | end 1119 | 1120 | // The clk/12 is set when Q[2]_delayed_by_2_cycle == 1 or Q[3] == 1 1121 | assign clk_out = Q_delay_2tp | Q[3]; 1122 | 1123 | endmodule 1124 | ``` 1125 | 1126 | [![go_back](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_go_back.png)](#contents) 1127 | 1128 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1129 | 1130 | ## Linear Feedback Shift Register (LFSR) 1131 | 1132 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1133 | 1134 | ## Sequence Detector 1135 | 1136 | A simple sequence detector can be modelled in several ways - 1137 | 1. Non-overlapping - Here, consider a sequence detector for sequence 1010. For the input sequence `10101010` the output will be `00010001`, i.e. the sequence is detected in a non-overlapping fashion. Once a sequence is detected, the sequence needs to be repeated completely from the start to be dected again. 1138 | 2. Overlapping - Again, consider a sequence detector for sequence 1010. For the input sequence `10101010` the output will be `00010101`, i.e. the sequence is detected in an overlapping fashion. Once a sequence is detected, a new sequence can be detected using a part of the previously detected sequence when applicable. 1139 | 1140 | Also, the state machine being used to detect the sequence can be mealy or a moore state machine. This will change the total number of states at some cost to the output functional logic 1141 | 1142 | ### Sequence Detector - 1010 1143 | 1144 | ![seqD_1010](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sequence_Detector/seqD_1010.png) 1145 | 1146 | Figure: Sequence Detector 1010 - Moore and Mealy; non-overlapping and overlapping state machines. 1147 | 1148 | ```verilog 1149 | // Code your design here 1150 | module seq_1010(input din, clk, rst, 1151 | output dout); 1152 | 1153 | // Parameterized state values for ease 1154 | parameter S0 = 0, S1 = 1, S2 = 2, S3 = 3, S4 = 4; 1155 | 1156 | // RState memory definition 1157 | reg [2:0] state, next_state; 1158 | 1159 | // Next State Logic - combinational logic to compute the next state based on the current state and input value 1160 | always @ (*) begin 1161 | case (state) 1162 | S0: next_state = din ? S1 : S0; 1163 | S1: next_state = din ? S1 : S2; 1164 | S2: next_state = din ? S3 : S0; 1165 | S3: next_state = din ? S1 : S4; 1166 | S4: next_state = din ? S1 : S0; // This transition for non-overlaping sequence detector (If uncommented, comment the next line) 1167 | //S4: next_state = din ? S3 : S0; // This transition for overlaping sequence detector (If uncommented, comment the previous line) 1168 | default: next_state = S0; 1169 | endcase 1170 | end 1171 | 1172 | // State Memory - Assign the computed next state to the state memory on the clock edge 1173 | always @ (posedge clk) begin 1174 | if (rst) state <= 3'b000; 1175 | else state <= next_state; 1176 | end 1177 | 1178 | // Output functional logic - The states for which the output should be '1' 1179 | assign dout = state == S4; 1180 | endmodule 1181 | ``` 1182 | 1183 | [![Run on EDA](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_run-on-eda-playground.png)](https://www.edaplayground.com/x/iK_p) 1184 | 1185 | ![moore_1010_wave1](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sequence_Detector/moore_1010_non_overlap.png) 1186 | 1187 | Figure: Sequence Detector 1010 - Moore non-overlapping waveform. 1188 | 1189 | 1190 | ![moore_1010_wave2](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sequence_Detector/moore_1010_overlap.png) 1191 | 1192 | Figure: Sequence Detector 1010 - Moore overlapping waveform. 1193 | 1194 | 1195 | ```verilog 1196 | // Code your design here 1197 | module seq_1010(input din, clk, rst, 1198 | output reg dout); 1199 | 1200 | // Parameterized state values for ease 1201 | parameter S0 = 0, S1 = 1, S2 = 2, S3 = 3; 1202 | 1203 | // RState memory definition 1204 | reg [1:0] state, next_state; 1205 | 1206 | // Next State Logic - combinational logic to compute the next state based on the current state and input value 1207 | always @ (*) begin 1208 | case (state) 1209 | S0: next_state = din ? S1 : S0; 1210 | S1: next_state = din ? S1 : S2; 1211 | S2: next_state = din ? S3 : S0; 1212 | S3: next_state = din ? S1 : S0;// This transition for non-overlaping sequence detector (If uncommented, comment the next line) 1213 | //S3: next_state = din ? S1 : S2; // This transition for overlaping sequence detector (If uncommented, comment the previous line) 1214 | default: next_state = S0; 1215 | endcase 1216 | end 1217 | 1218 | // State Memory - Assign the computed next state to the state memory on the clock edge 1219 | always @ (posedge clk) begin 1220 | if (rst) state <= 2'b00; 1221 | else state <= next_state; 1222 | end 1223 | 1224 | // Output functional logic - The states for which the output should be '1' 1225 | always @ (posedge clk) begin 1226 | if (rst) dout <= 1'b0; 1227 | else begin 1228 | if (~din & (state == S3)) dout <= 1'b1; 1229 | else dout <= 1'b0; 1230 | end 1231 | end 1232 | endmodule 1233 | ``` 1234 | 1235 | [![Run on EDA](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_run-on-eda-playground.png)](https://www.edaplayground.com/x/HbJV) 1236 | 1237 | ![mealy_1010_wave1](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sequence_Detector/mealy_1010_non_overlap.png) 1238 | 1239 | Figure: Sequence Detector 1010 - Mealy non-overlapping waveform. 1240 | 1241 | ![mealy_1010_wave2](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sequence_Detector/mealy_1010_overlap.png) 1242 | 1243 | Figure: Sequence Detector 1010 - Mealy overlapping waveform. 1244 | 1245 | The sequence can also be detected using a simple n-bit shift register, where "n" represents the length of the sequence to be detected (in this case 4) and a comparator can be used to check the state of these n-bit registers. However, consider a sequence which has 20 bits, then we will need a 20 bit shift register which happens to be extremely costly in terms of area. The same can be acheived using a state machine with just 5 flip-flops and some additional combinational logic. 1246 | 1247 | ![seqD_1010_shiftReg](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sequence_Detector/seqD_1010_shiftReg.png) 1248 | 1249 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1250 | 1251 | ### Sequence Detector - 1001 1252 | 1253 | ![seqD_1001](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sequence_Detector/seqD_1001.png) 1254 | 1255 | ```verilog 1256 | module seq_1001_moore (input din, clk, rst, 1257 | output dout); 1258 | 1259 | // Parameterized state values for ease 1260 | parameter S0 = 0, S1 = 1, S2 = 2, S3 = 3, S4 = 4; 1261 | 1262 | // RState memory definition 1263 | reg [2:0] state, next_state; 1264 | 1265 | // Next State Logic - combinational logic to compute the next state based on the current state and input value 1266 | always @ (*) begin 1267 | case (state) 1268 | S0: next_state = din ? S1 : S0; 1269 | S1: next_state = din ? S1 : S2; 1270 | S2: next_state = din ? S1 : S3; 1271 | S3: next_state = din ? S4 : S0; 1272 | S4: next_state = din ? S1 : S0; // This transition for non-overlaping sequence detector (If uncommented, comment the next line) 1273 | //S4: next_state = din ? S1 : S2; // This transition for overlaping sequence detector (If uncommented, comment the previous line) 1274 | default: next_state = S0; 1275 | endcase 1276 | end 1277 | 1278 | // State Memory - Assign the computed next state to the state memory on the clock edge 1279 | always @ (posedge clk) begin 1280 | if (rst) state <= 3'b000; 1281 | else state <= next_state; 1282 | end 1283 | 1284 | // Output functional logic - The states for which the output should be '1' 1285 | assign dout = state == S4; 1286 | endmodule 1287 | ``` 1288 | 1289 | [![Run on EDA](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_run-on-eda-playground.png)](https://www.edaplayground.com/x/9V9V) 1290 | 1291 | ![mealy_1001_wave1](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sequence_Detector/mealy_1010_non_overlap.png) 1292 | 1293 | Figure: Sequence Detector 1001 - Mealy non-overlapping waveform. 1294 | 1295 | ![mealy_1001_wave2](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sequence_Detector/mealy_1010_overlap.png) 1296 | 1297 | Figure: Sequence Detector 1001 - Mealy overlapping waveform. 1298 | 1299 | ```verilog 1300 | module seq_1001_mealy (input din, clk, rst, 1301 | output reg dout); 1302 | 1303 | // Parameterized state values for ease 1304 | parameter S0 = 0, S1 = 1, S2 = 2, S3 = 3; 1305 | 1306 | // RState memory definition 1307 | reg [2:0] state, next_state; 1308 | 1309 | // Next State Logic - combinational logic to compute the next state based on the current state and input value 1310 | always @ (*) begin 1311 | case (state) 1312 | S0: next_state = din ? S1 : S0; 1313 | S1: next_state = din ? S1 : S2; 1314 | S2: next_state = din ? S1 : S3; 1315 | S3: next_state = S0;// This transition for non-overlaping sequence detector (If uncommented, comment the next line) 1316 | //S3: next_state = din ? S1 : S0; // This transition for overlaping sequence detector (If uncommented, comment the previous line) 1317 | default: next_state = S0; 1318 | endcase 1319 | end 1320 | 1321 | // State Memory - Assign the computed next state to the state memory on the clock edge 1322 | always @ (posedge clk) begin 1323 | if (rst) state <= 2'b00; 1324 | else state <= next_state; 1325 | end 1326 | 1327 | // Output functional logic - The states for which the output should be '1' 1328 | always @ (posedge clk) begin 1329 | if (rst) dout <= 1'b0; 1330 | else begin 1331 | if (din & (state == S3)) dout <= 1'b1; 1332 | else dout <= 1'b0; 1333 | end 1334 | end 1335 | endmodule 1336 | ``` 1337 | 1338 | [![Run on EDA](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_run-on-eda-playground.png)](https://www.edaplayground.com/x/7VVS) 1339 | 1340 | ![mealy_1001_wave1](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sequence_Detector/mealy_1010_non_overlap.png) 1341 | 1342 | Figure: Sequence Detector 1001 - Mealy non-overlapping waveform. 1343 | 1344 | ![mealy_1001_wave2](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sequence_Detector/mealy_1010_overlap.png) 1345 | 1346 | Figure: Sequence Detector 1001 - Mealy overlapping waveform. 1347 | 1348 | [![go_back](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_go_back.png)](#contents) 1349 | 1350 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1351 | 1352 | ## Register File 1353 | 1354 | Register File is a type of memory block (typically used in a CPU), a m-set of storage cells to store data n-bit wide. It is used to hold data and fetch data based on the need. To perform this function, the register has the ***write operation*** to enable writing data to the register locations and ***read operation*** to enable reading the register locations. To write and read data the register file has ***write pointer*** and ***read pointer*** inputs which can be in a binary encoded or one-hot coded fashion. The number of writes and reads that can be performed in a clock cycle decide the number of ***write port*** and ***read ports*** needed in a register file. 1355 | 1356 | The most common use of a register file is in a CPU in which we can perform a write to store the computed data and 2 reads to fetch data operands to operate on in a clock cycle. For this reason, we will design a register file with 1 write port and 2 read ports. 1357 | 1358 | At the transistor level, register file can be an array of flip flops. However, in larger designs this is costlier and it is implemented through SRAM cells. However, with an SRAM cell array there is additional considerations of read and write cycles. 1359 | 1360 | ![register_file](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Register_File/register_file.png) 1361 | 1362 | Figure: Register file with 1 write port and 2 read ports 1363 | 1364 | Register file operations include: 1365 | 1. ***Register File Read Operation:*** A ***read address*** value is provided on the ***read address port*** to select the register to be read from. The ***read data*** is available immediately through the mux coming out on the ***read data port***. 1366 | 2. ***Register File Write Operation:*** A ***write address*** value is provided on the ***write address port*** to select the register to which data is to be written and ***write data*** value is provided on the ***write data port*** which is the data to be written to. 1367 | 1368 | ```verilog 1369 | module RegisterFile ( input clk, srst, reg_write, 1370 | input [7:0] w_data, 1371 | input [2:0] r_addr1, r_addr2, w_addr, 1372 | output [7:0] r_data1, r_data2); 1373 | 1374 | // Register memory array - 8 locations of 8 bits each 1375 | reg [7:0] register [0:7]; 1376 | 1377 | integer i; 1378 | 1379 | always @ (posedge clk) begin 1380 | if (srst) begin 1381 | 1382 | // Initialize all registers to value 0 1383 | for(i = 0; i < 8; i=i+1) begin 1384 | register[i] <= 'h0; 1385 | end 1386 | end 1387 | else if (reg_write) 1388 | 1389 | // Write to registers only on condition reg_write 1390 | // On reg_write, write the data to the register address provided on w_addr 1391 | register[w_addr] <= w_data; 1392 | end 1393 | 1394 | // Read data available on 2 read ports based on 2 seperate read addresses 1395 | assign r_data1 = register[r_addr1]; 1396 | assign r_data2 = register[r_addr2]; 1397 | 1398 | endmodule 1399 | ``` 1400 | 1401 | [![Run on EDA](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_run-on-eda-playground.png)](https://www.edaplayground.com/x/hj7Y) 1402 | 1403 | ![reg_file_wave](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Register_File/reg_file_wave.png) 1404 | 1405 | [![go_back](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_go_back.png)](#contents) 1406 | 1407 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1408 | 1409 | ## First-in-first-out (FIFO) 1410 | 1411 | In this day, almost every digital component works on a clock and it is very common that the sub-systems exchange data for computational and operational needs. An intermediary becomes necessary if: 1412 | - The data produced and the data consumer operate on different clock frequencies 1413 | - If the data is being produced at a slower speed than the data is being consumed ***(f_write_clk < f_read_clk)*** the data transfer can take place through a single data register followed by asynchronous data synchronization methods (handshake or 2-clock synchronization) 1414 | - If the data is being produced at a higher speed than the data is being consumed ***(f_write_clk > f_read_clk)*** the data transfer needs buffering which can be implemented through an asynchronous FIFO. The depth of the FIFO depends the write and read clock and the maximum data burst length. 1415 | - The data producer and the data consumer have a skew between their clocks 1416 | - If the data is being produced at the same speed as the data is being consumed ***(f_write_clk = f_read_clk)*** and there is a skew between the producer and the consumer clock, the data can be transferred through a lock-up latch/register to overcome the skew 1417 | - There is a skew between the data production burst and data reception burst 1418 | - If the producer and consumer operate at the same clock but have a large skew between when a burst of data is produced and when the burst of data is consumed. In such scenario, the produced data needs to be buffered and the sequence of transfer needs to be preserved, then a synchronous FIFO can be used. The depth of such FIFO is decided by the maximum burst length 1419 | 1420 | 1421 | Additional information can be found at [FIFO Architecture, Functions, and Applications](https://www.ti.com/lit/an/scaa042a/scaa042a.pdf) 1422 | 1423 | Additional info on deciding the fifo depth can be found at [Calculation of FIFO Depth](https://hardwaregeeksblog.files.wordpress.com/2016/12/fifodepthcalculationmadeeasy2.pdf) 1424 | 1425 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1426 | 1427 | ### Synchronous FIFO 1428 | 1429 | ***Synchronous FIFO*** - The type of FIFOs which have common write and read clock are called synchronous FIFO. Synchronous FIFOs are very common in a processor/controller ICs which work on a common system clock. Since all the sub-systems work on the same system clock they can make use of sync-FIFOs with a possible need for skew handling. 1430 | 1431 | ![fifo_sync](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/FIFO/fifo_sync.png) 1432 | 1433 | ```verilog 1434 | module fifo(input clk, rst, wen, ren, 1435 | input [7:0] din, 1436 | output full, empty, 1437 | output reg [7:0] dout); 1438 | 1439 | // FIFO memory array - 8 locations of 8 bits each 1440 | reg [7:0] mem [0:7]; 1441 | 1442 | // FIFO write and read pointer registers (n+1) bit wide 1443 | reg [3:0] wptr, rptr; 1444 | 1445 | // read enable and write enable qualified signals declaration 1446 | wire wenq, renq; 1447 | 1448 | // Computation of full and empty signals based on the current 1449 | // read and qrite pointers 1450 | assign full = ((wptr ^ rptr) == 4'b1000); 1451 | assign empty = (wptr == rptr); 1452 | 1453 | // read enable qualified and write enable qualified are generated 1454 | // based on the write/read request and full and empty status of FIFO 1455 | assign wenq = ~full & wen; 1456 | assign renq = ~empty & ren; 1457 | 1458 | always @ (posedge clk) begin 1459 | 1460 | if (rst) begin 1461 | // Write and read pointers are initialized to 0 1462 | wptr <= 4'b0000; 1463 | rptr <= 4'b0000; 1464 | 1465 | // FIFO memory is initialized to 0 (not necessary) 1466 | for (integer i = 0; i < 8; i = i + 1) 1467 | mem[i] = 8'h00; 1468 | end 1469 | else begin 1470 | // Write pointer is incremented on valid write request 1471 | // FIFO memory is updated with data for valid write request 1472 | if (wenq) begin 1473 | wptr <= wptr + 1; 1474 | mem[wptr] <= din; 1475 | end 1476 | else begin 1477 | wptr <= wptr; 1478 | mem[wptr] <= mem[wptr[2:0]]; 1479 | end 1480 | 1481 | // Read pointer is incremented on valid read request 1482 | if (renq) 1483 | rptr <= rptr + 1; 1484 | else 1485 | rptr <= rptr; 1486 | end 1487 | end 1488 | 1489 | // Read data port 1490 | assign dout = mem[rptr[2:0]]; 1491 | 1492 | endmodule 1493 | ``` 1494 | 1495 | [![Run on EDA](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_run-on-eda-playground.png)](https://www.edaplayground.com/x/KpjL) 1496 | 1497 | ![fifo_sync_wave](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/FIFO/fifo_sync_wave.png) 1498 | 1499 | [![go_back](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_go_back.png)](#contents) 1500 | 1501 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1502 | 1503 | ### Synchronous FIFO with odd depth 1504 | 1505 | Typically, a FIFO has ***2^n*** locations and for such a FIFO a ***n+1*** bit write and read pointers are used. However, in a FIFO with odd depth, i.e., which has locations not equal to ***2^n*** we will continue to use a ***n+1*** bit write and read pointers but these will be implemented as a mod-n counter. 1506 | 1507 | For example, say we need to design a FIFO with 6 locations we need 4-bit read and write pointers of which the lower three bits will sequence from `3'b000, 3'b001, 3'b010, 3'b011, 3'b100, 3'b101` to point to the FIFO memory locations. 1508 | 1509 | The same can be modelled in verilog as, 1510 | 1511 | ```verilog 1512 | module FIFO(input clk, wen, ren, rst, 1513 | input [7:0] data_in, 1514 | output full, empty, 1515 | output [7:0] data_out); 1516 | 1517 | // FIFO write and read pointer registers (n+1) bit wide 1518 | reg [3:0] wptr, rptr; 1519 | 1520 | // FIFO memory array - 8 locations of 8 bits each 1521 | reg [7:0] mem [0:5]; 1522 | 1523 | // Computation of full and empty signals based on the current 1524 | // read and qrite pointers 1525 | assign full = (wptr ^ rptr) == 4'h8; 1526 | assign empty = wptr == rptr; 1527 | 1528 | // read enable qualified and write enable qualified are generated 1529 | // based on the write/read request and full and empty status of FIFO 1530 | assign wenq = ~full & wen; 1531 | assign renq = ~empty & ren; 1532 | 1533 | always @ (posedge clk) begin 1534 | if (rst) begin 1535 | // FIFO memory is initialized to 0 (not necessary) 1536 | for (integer i = 0; i < 8; i=i+1) 1537 | mem[i] <= 8'h00; 1538 | 1539 | // Write and read pointers are initialized to 0 1540 | wptr <= 4'h0; 1541 | rptr <= 4'h0; 1542 | end 1543 | else begin 1544 | // Write pointer is incremented on valid write request 1545 | // FIFO memory is updated with data for valid write request 1546 | if (wenq) begin 1547 | if (wptr[2:0] == 3'b101) 1548 | wptr <= {~wptr[3], 3'b000}; 1549 | else 1550 | wptr <= wptr+1; 1551 | mem[wptr[2:0]] <= datain; 1552 | end 1553 | 1554 | // Read pointer is incremented on valid read request 1555 | if (renq) begin 1556 | if (rptr[2:0] == 3'b101) 1557 | rptr <= {~rptr[3], 3'b000}; 1558 | else 1559 | rptr <= rptr+1; 1560 | end 1561 | end 1562 | end 1563 | 1564 | // Read data port 1565 | assign dataout = mem[rptr[2:0]]; 1566 | 1567 | endmodule 1568 | ``` 1569 | 1570 | [![Run on EDA](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_run-on-eda-playground.png)](https://www.edaplayground.com/x/Jmkw) 1571 | 1572 | [![go_back](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_go_back.png)](#contents) 1573 | 1574 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1575 | 1576 | ### Asynchronous FIFO 1577 | 1578 | ***Asynchronous FIFO*** - The type of FIFOs which have different write and read clock are called asynchronous FIFO. Such FIFO block is typically used when data needs to be transferred across clock-domain-crossing (CDC), where both the producer and the consumer work in different clock domain. 1579 | 1580 | [![Run on EDA](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_run-on-eda-playground.png)](https://www.edaplayground.com/x/fabv) 1581 | 1582 | [![go_back](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_go_back.png)](#contents) 1583 | 1584 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1585 | 1586 | ## Last in first out (LIFO) 1587 | 1588 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1589 | 1590 | ## Round robin arbiter 1591 | 1592 | [![go_back](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_go_back.png)](#contents) 1593 | 1594 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1595 | 1596 | # References 1597 | 1598 | 1599 | [Click here](https://www.chipverify.com/verilog/verilog-tutorial) to visit website with extensive documentation of verilog 1600 | 1601 | [Click here](http://www.eng.auburn.edu/~nelsovp/courses/elec4200/VHDL/Verilog_Overview_4200.pdf) to visit an exceptional compilation of basic verilog for ASIC design 1602 | 1603 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1604 | 1605 | # About and Contact Info 1606 | 1607 | Website Version: 1.08.054 1608 | -------------------------------------------------------------------------------- /Register_File/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Register_File/.DS_Store -------------------------------------------------------------------------------- /Register_File/README.md: -------------------------------------------------------------------------------- 1 | # Register File 2 | -------------------------------------------------------------------------------- /Register_File/RegisterFile.v: -------------------------------------------------------------------------------- 1 | module RegisterFile ( input CLK, RST, RegWrite, 2 | input [0:63] W_DATA, 3 | input [0:4] R_ADDR1, R_ADDR2, W_ADDR, 4 | input [0:7] W_MASK, 5 | output [0:63] OUT1,OUT2); 6 | 7 | reg [0:63] REGISTER [0:32]; 8 | 9 | integer i; 10 | 11 | always @(posedge CLK) begin 12 | if (RST) begin 13 | for(i = 0; i < 32; i=i+1) begin 14 | REGISTER[i] <= 64'h0; 15 | end 16 | end 17 | else if (RegWrite & W_ADDR != 5'd0) 18 | for (i = 0; i < 8 ; i= i+1) begin 19 | REGISTER[W_ADDR][8*i+:8] <= W_MASK[i] == 1'b1 ? W_DATA[8*i+:8] : REGISTER[W_ADDR][8*i+:8]; 20 | end 21 | end 22 | 23 | assign OUT1 = (RegWrite & (W_ADDR == R_ADDR1) & (W_ADDR != 5'd0)) ? W_DATA : REGISTER[R_ADDR1]; 24 | assign OUT2 = (RegWrite & (W_ADDR == R_ADDR2) & (W_ADDR != 5'd0)) ? W_DATA : REGISTER[R_ADDR2]; 25 | 26 | endmodule 27 | -------------------------------------------------------------------------------- /Register_File/RegisterFile_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/1ns 2 | 3 | module test_RegisterFile(); 4 | 5 | reg CLK, RST; 6 | 7 | always #1 CLK = ~CLK; 8 | reg W_EN; 9 | reg [0:63] W_DATA; 10 | reg [0:4] W_ADDR, R_ADDR1, R_ADDR2; 11 | reg [0:63] R_DATA1, R_DATA2; 12 | reg [0:7] W_MASK; 13 | integer i; 14 | 15 | RegisterFile REG1 (.CLK(CLK), 16 | .RST(RST), 17 | .RegWrite(W_EN), 18 | .W_ADDR(W_ADDR), 19 | .W_DATA(W_DATA), 20 | .R_ADDR1(R_ADDR1), 21 | .R_ADDR2(R_ADDR2), 22 | .OUT1(R_DATA1), 23 | .OUT2(R_DATA2), 24 | .W_MASK(W_MASK)); 25 | initial begin 26 | check_REGISTER; 27 | end 28 | 29 | initial begin 30 | $dumpfile("dump.vcd"); 31 | $dumpvars(1); 32 | end 33 | 34 | task check_REGISTER(); begin 35 | RST = 1'b1; 36 | CLK = 1'b0; 37 | W_EN = 1'b0; 38 | W_ADDR = 5'b0; 39 | R_ADDR1 = 5'b0; 40 | R_ADDR2 = 5'b0; 41 | W_DATA = 64'h0; 42 | W_MASK = 8'hFF; 43 | 44 | #4 RST = 1'b0; 45 | 46 | #2 W_EN = 1'b1; W_ADDR = 5'h0; W_DATA = 64'hFFFF; 47 | for (i = 0; i < 32; i=i+1) begin 48 | #2 W_ADDR = i; W_DATA = i+65536; 49 | end 50 | 51 | #2 W_EN = 1'b0; W_ADDR = 0; W_DATA = 0; 52 | 53 | #2 54 | 55 | for (i = 0; i < 32; i=i+1) begin 56 | #2 R_ADDR1 = i; R_ADDR2 = i; 57 | end 58 | 59 | #2 W_EN = 1'b1; W_ADDR = 5; W_DATA = 25; R_ADDR1 = 5; R_ADDR2 = 5; 60 | 61 | #2 W_EN = 1'b0; W_ADDR = 0; W_DATA = 0; R_ADDR1 = 4; R_ADDR2 = 4; 62 | 63 | #2 R_ADDR1 = 5; R_ADDR2 = 5; 64 | 65 | #5 $stop; 66 | end 67 | endtask 68 | 69 | 70 | endmodule 71 | 72 | 73 | -------------------------------------------------------------------------------- /Register_File/reg_file_wave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Register_File/reg_file_wave.png -------------------------------------------------------------------------------- /Register_File/register_file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Register_File/register_file.png -------------------------------------------------------------------------------- /Round_Robin_Arbiter/README.md: -------------------------------------------------------------------------------- 1 | # Verilog 2 | Logic Design using Verilog 3 | -------------------------------------------------------------------------------- /SIPO/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/SIPO/.DS_Store -------------------------------------------------------------------------------- /SIPO/README.md: -------------------------------------------------------------------------------- 1 | # Verilog 2 | Logic Design using Verilog 3 | -------------------------------------------------------------------------------- /SIPO/SIPO.v: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /SIPO/SIPO_tb.v: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /SIPO/sipo_basic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/SIPO/sipo_basic.png -------------------------------------------------------------------------------- /SIPO/sipo_capture_reg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/SIPO/sipo_capture_reg.png -------------------------------------------------------------------------------- /Sequence_Detector/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Sequence_Detector/.DS_Store -------------------------------------------------------------------------------- /Sequence_Detector/README.md: -------------------------------------------------------------------------------- 1 | # Verilog 2 | Logic Design using Verilog 3 | -------------------------------------------------------------------------------- /Sequence_Detector/mealy_1010_non_overlap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Sequence_Detector/mealy_1010_non_overlap.png -------------------------------------------------------------------------------- /Sequence_Detector/mealy_1010_overlap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Sequence_Detector/mealy_1010_overlap.png -------------------------------------------------------------------------------- /Sequence_Detector/moore_1010_non_overlap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Sequence_Detector/moore_1010_non_overlap.png -------------------------------------------------------------------------------- /Sequence_Detector/moore_1010_overlap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Sequence_Detector/moore_1010_overlap.png -------------------------------------------------------------------------------- /Sequence_Detector/seqD_1001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Sequence_Detector/seqD_1001.png -------------------------------------------------------------------------------- /Sequence_Detector/seqD_1010.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Sequence_Detector/seqD_1010.png -------------------------------------------------------------------------------- /Sequence_Detector/seqD_1010_ROM.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Sequence_Detector/seqD_1010_ROM.jpg -------------------------------------------------------------------------------- /Sequence_Detector/seqD_1010_ROM1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Sequence_Detector/seqD_1010_ROM1.png -------------------------------------------------------------------------------- /Sequence_Detector/seqD_1010_ROM_SM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Sequence_Detector/seqD_1010_ROM_SM.png -------------------------------------------------------------------------------- /Sequence_Detector/seqD_1010_shiftReg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Sequence_Detector/seqD_1010_shiftReg.png -------------------------------------------------------------------------------- /Shifter_Rotator/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Shifter_Rotator/.DS_Store -------------------------------------------------------------------------------- /Shifter_Rotator/README.md: -------------------------------------------------------------------------------- 1 | # Verilog 2 | Logic Design using Verilog 3 | -------------------------------------------------------------------------------- /Shifter_Rotator/right_left_rotator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Shifter_Rotator/right_left_rotator.png -------------------------------------------------------------------------------- /Shifter_Rotator/right_left_shifter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Shifter_Rotator/right_left_shifter.png -------------------------------------------------------------------------------- /Shifter_Rotator/right_rotator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Shifter_Rotator/right_rotator.png -------------------------------------------------------------------------------- /Shifter_Rotator/right_shifter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Shifter_Rotator/right_shifter.png -------------------------------------------------------------------------------- /Shifter_Rotator/shifter_rotator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Shifter_Rotator/shifter_rotator.png -------------------------------------------------------------------------------- /Sorting_Network/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Sorting_Network/.DS_Store -------------------------------------------------------------------------------- /Sorting_Network/README.md: -------------------------------------------------------------------------------- 1 | # Verilog 2 | Logic Design using Verilog 3 | -------------------------------------------------------------------------------- /Sorting_Network/cas_block.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Sorting_Network/cas_block.png -------------------------------------------------------------------------------- /Sorting_Network/sorting_network_4nos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Sorting_Network/sorting_network_4nos.png -------------------------------------------------------------------------------- /Sorting_Network/sorting_network_8nos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Sorting_Network/sorting_network_8nos.png -------------------------------------------------------------------------------- /Sorting_Network/sorting_network_blocks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sumukhathrey/Verilog_ASIC_Design/77dff213c25c8d4228254d4eb3d9e0e349b2a420/Sorting_Network/sorting_network_blocks.png -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman 2 | -------------------------------------------------------------------------------- /about.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: About 3 | layout: template 4 | filename: about.md 5 | --- 6 | 7 | Verilog 8 | Click here to visit website with extensive documentation of verilog 9 | 10 | Click here to visit an exceptional compilation of basic verilog for ASIC design 11 | 12 | -------------------------------------------------------------------------------- /index.md: -------------------------------------------------------------------------------- 1 | # Contents 2 | 3 | - [Types of Verilog Modelling](#types-of-verilog-modelling) 4 | 5 | - [Verilog Coding Style](#verilog-coding-style) 6 | 7 | - [Latches in Verilog](#latches-in-verilog) 8 | 9 | - [Basic hardware components](#basic-hardware-components) 10 | 11 | | [Adders](#adders) | [Shifter and Rotator](#shifter-and-rotator) | [Multiplier](#multiplier) | 12 | | ------- | ------- | ------- | 13 | | [Divider](#divider) | [Sorting network](#sorting-network) | [D flip-flop](#d-flip-flop) | 14 | | [Serial in parallel out (SIPO)](#serial-in-parallel-out-sipo) | [Parallel in serial out (PISO)](#parallel-in-serial-out-piso) | [Counters](#counters) | 15 | | [MOD-N counters](#mod-n-counters) | [Gray counter](#gray-counter) | [Fibonacci counter](#fibonacci-counter) | 16 | | [Frequency Dividers](#frequency-dividers) | [Linear feedback shift register (LFSR)](#linear-feedback-shift-register-LFSR) | [Sequence Detector](#sequence-detector) | 17 | | [Register File](#register-file) | [First-in-first-out (FIFO)](#first-in-first-out-fifo) | [Last-in-first-out (LIFO)](#last-in-first-out-lifo) | 18 | | [Round robin arbiter](#round-robin-arbiter) | | | 19 | 20 | - Single-cycle CPU 21 | 22 | - Multi-cycle CPU 23 | 24 | - Pipelined CPU 25 | 26 | - Tomasulo CPU 27 | 28 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 29 | 30 | # Types of Verilog Modelling 31 | Verilog is one of the Hardware Description Language (HDL) used to model the electronics systems at the following abstraction levels: 32 | 33 | 1. Register Transfer Level (RTL) - An abstraction level, where the circuits are modelled as the flow of data between registers. This is achieved through always blocks and assign statements. The RTL should be written in a way such that it is completely synthesizable, i.e., can be translated/synthesized to gate level 34 | 35 | 2. Behavioral - An abstraction level, which mimics the desired functionality of the hardware but is not necessarily synthesizable. Behavioral verilog is often used to represent analog block, place holder code, testbench code, and most importantly for modelling hardware for behavioral simulation. 36 | 37 | 3. Structural - Logic described by gates and modules only. No always blocks or assign statements. This is a representative of the real gates in the hardware. 38 | 39 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 40 | 41 | # Verilog Coding Style 42 | 43 | Here, we will try to create exaples of hardware using RTL model and test it using an appropriate testbench. 44 | 45 | The basic structure of code we will follow for hardware modelling the design is as follows: 46 | 47 | ```verilog 48 | module design_name (input , 49 | output ); 50 | 51 | //internal registers and wires 52 | reg ; 53 | wire ; 54 | 55 | //combinational logic for next-state-logic 56 | always @ (*) begin 57 | //Combinational Statements using blocking assignments 58 | end 59 | 60 | //sequential logic for state-memory 61 | always @ (posedge clk) begin 62 | //Sequential Statements with non-blocking assignments 63 | //Reset statement necessary 64 | end 65 | 66 | //combinational logic for output-functional-logic 67 | assign = ; 68 | endmodule 69 | ``` 70 | 71 | The basic structure of code we will follow for creating a testbench to test the design is as follows: 72 | 73 | ```verilog 74 | module design_name_tb (); 75 | 76 | //internal registers and wires 77 | reg ; // All design inputs should be registers 78 | wire ; // All design outputs can be wires 79 | 80 | //initialize the design 81 | design_name (.input_port_names(reg_names), .output_port_names(wire_names)); 82 | 83 | //If the design has clock, create a clock (here clock period = 2ns) 84 | always #1 clk = ~clk 85 | 86 | //test vectors input 87 | initial begin 88 | // initialize all inputs to initial values 89 | 90 | // write the input vectors here 91 | 92 | #5 $stop; //terminate the simulation 93 | end 94 | endmodule 95 | ``` 96 | 97 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 98 | 99 | # Latches in Verilog 100 | 101 | The latch is modelled in verilog as 102 | 103 | ```verilog 104 | module d_latch (input en, d, 105 | output q); 106 | always @ (*) begin 107 | if (clk) 108 | q = d; 109 | end 110 | endmodule 111 | ``` 112 | 113 | However, sometines a latch can be inferred in a verilog code unexpectedly due to incorrect coding practice such as when a combinational logic has undefined states. These can be - 114 | 1. Signal missing in the sensitivity list 115 | 116 | ```verilog 117 | always @(a or b) 118 | begin 119 | out = a + b + c; // Here, a latch is inferred for c, 120 | // since it is missing from sensitivity list 121 | end 122 | ``` 123 | 124 | 125 | 2. Coverage not provided for all cases in an if-statement or case-statement 126 | 127 | In the following case , we have a case where q = d for en = 1. However, the tool does not know what to do when en = 0, and infers a latch 128 | ```verilog 129 | always @(d or q) 130 | begin 131 | if (en) q = d; // Condition missing for en = 0; previous value 132 | // will be held through latch 133 | end 134 | ``` 135 | Similarly, in the following case, if default case is missing in case statement and we don't have coverage for all possible cases, a latch is inferred. 136 | ```verilog 137 | always @(d or q) 138 | begin 139 | case (d) 140 | 2'b00: q = 0; 141 | 2'b01: q = 1; 142 | 2'b10: q = 1; // default condition missing; latch will be 143 | // inferred for condition d = 2'b11 to hold the 144 | // previous value 145 | endcase 146 | end 147 | ``` 148 | 149 | ***Note: Latches are only generated by combinational always blocks, the sequential always block will never generate a latch.*** 150 | 151 | 152 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 153 | 154 | # Basic hardware components 155 | 156 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 157 | 158 | ## Adders 159 | 160 | ### Half adder 161 | 162 | The half adder circuit is realized as shown in Figure 1. The block has two inputs ***a*** & ***b***, and two outputs ***sum*** and ***cout*** 163 | 164 | ![half_adder](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/half_adder.png) 165 | 166 | The same can be written in verilog as - 167 | 168 | ```verilog 169 | module half_adder (input a, b, 170 | output sum, cout); 171 | assign sum = a ^ b; 172 | assign cout = a & b; 173 | endmodule 174 | ``` 175 | 176 | ```verilog 177 | module full_adder (input a, b, 178 | output sum, cout); 179 | assign {cout, sum} = a + b; 180 | endmodule 181 | ``` 182 | 183 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 184 | 185 | ### Full adder 186 | 187 | The half adder circuit is realized as shown in Figure 1. The block has two inputs ***a***, ***b*** & ***cin***, and two outputs ***sum*** and ***cout*** 188 | 189 | ![full_adder](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/full_adder.png) 190 | 191 | The same can be written in verilog in many different ways- 192 | 193 | ```verilog 194 | module full_adder (input a, b, cin, 195 | output sum, cout); 196 | wire x, y, z; 197 | assign x = a ^ b; 198 | assign sum = x ^ cin; 199 | assign y = a & b; 200 | assign z = x & cin; 201 | assign cout = y | z; 202 | endmodule 203 | ``` 204 | 205 | ```verilog 206 | module full_adder (input a, b, cin, 207 | output sum, cout); 208 | assign {cout, sum} = a + b + cin; 209 | endmodule 210 | ``` 211 | 212 | ```verilog 213 | module full_adder (input a, b, cin, 214 | output sum, cout); 215 | assign sum = a ^ b ^ cin; 216 | assign cout = (a & b) | ((a ^ b) & cin); 217 | endmodule 218 | ``` 219 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 220 | 221 | ## Shifter and Rotator 222 | 223 | ![shifter](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Shifter_Rotator/right_shifter.png) 224 | 225 | ![shifter_lr](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Shifter_Rotator/right_left_shifter.png) 226 | 227 | ![rotator](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Shifter_Rotator/right_rotator.png) 228 | 229 | ![rotator_lr](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Shifter_Rotator/right_left_rotator.png) 230 | 231 | ![rotator_shifter](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Shifter_Rotator/shifter_rotator.png) 232 | 233 | 234 | Additional information can be found at [Design alternatives for barrel shifters](https://www.princeton.edu/~rblee/ELE572Papers/Fall04Readings/Shifter_Schulte.pdf) 235 | 236 | [![go_back](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_go_back.png)](#contents) 237 | 238 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 239 | 240 | ## Multiplier 241 | 242 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 243 | 244 | ## Divider 245 | 246 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 247 | ## Sorting network 248 | 249 | Sorting is a very important task generally performed through software, however, in hing sorting demand operations such as artificial intelligence and databases it becomes a necessity to implement sorting through hardware to speedup the process. This is implemented in hardware through a basic building block called ***compare and swap (CAS)*** block. The CAS block is connected in a certain way called bitonic network to sort the given set of numbers. 250 | 251 | ![sorting_networks_cas_blocks](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sorting_Network/cas_block.png) 252 | 253 | Figure 1: Compare and Swap Block 254 | 255 | The CAS block has two inputs, ***A*** and ***B*** and has two outputs ***O1 = max(A,B)*** and ***O2 = min(A,B)***. A CAS block is made up of an n-bit comparator, two n-bit multiplexers to select from inputs A and B where n-bit is the data width of A and B. There can be two configurations of the CAS block to sort the numbers in an ascending or descending order. 256 | 257 | To differentiate between the ascending and decending order CAS blocks, we use arrows to depict the type of sort. The arrow-head indicates port with ***max*** output and the arrow-root indicates the port with the ***min*** output. 258 | 259 | ```verilog 260 | module comapre_and_swap(input [3:0] data1, data2, 261 | output [3:0] max, min); 262 | 263 | // Comparator output declaration 264 | wire data1_greater_than_data2; 265 | 266 | // Comparator output = 1 if data1 > data2 267 | // Comparator output = 0 if data1 <= data2 268 | assign data1_greater_than_data2 = data1 > data2; 269 | 270 | // max data 271 | assign max = (data1_greater_than_data2 == 1'b1) ? data1 : data2; 272 | 273 | // min data 274 | assign min = (data1_greater_than_data2 == 1'b1) ? data2 : data1; 275 | 276 | endmodule 277 | ``` 278 | 279 | ![sorting_networks_components](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sorting_Network/sorting_network_blocks.png) 280 | 281 | Figuren 2: Ascending and descending CAS blocks 282 | 283 | ### Bitonic Sorting Networks 284 | 285 | A sorting network is a combination of CAS blocks, where each CAS block takes two inputs and swaps it if required, based on its ascending or descending configuration. ***Bitonic sorting networks*** uses the procedure of ***bitonic merge (BM)***, given two equal size sets of input data, sorted in opposing directions, the BM procedure will create a combined set of sorted data. It recursively merges an ascending and a descending set of size N /2 to make a sorted set of size N. Figure 3 and Figure 4 shows the CAS network for a 4-input and 8-input bitonic sorting network made up of ascending and descending BM units. 286 | 287 | The total number of CAS blocks in any N-input bitonic sorting is N × log2 ( N ) × (log2( N ) + 1)/4. The following table shows the CAS blocks needed for N-input bitonic networks. 288 | 289 | | Input data numbers | 8 | 16 | 32 | 256 | 290 | | ------------------ | -- | -- | -- | --- | 291 | | CAS blocks needed in sorting network | 24 | 80 | 240 | 4608 | 292 | 293 | ![sorting_networks_4nos](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sorting_Network/sorting_network_4nos.png) 294 | 295 | Figure 3: Sorting 4 numbers using CAS blocks in ascending and descending order 296 | 297 | ![sorting_networks_8nos](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sorting_Network/sorting_network_8nos.png) 298 | 299 | Figure 4: Sorting 8 numbers using CAS blocks in ascending order 300 | 301 | ```verilog 302 | module sort_network_8x4 (input [3:0] data_in [0:7], 303 | output [3:0] data_sort [0:7]); 304 | 305 | // wire declarations for all the sorting intermediaries 306 | wire [3:0] stage1 [0:7]; 307 | 308 | wire [3:0] stage2_0 [0:7]; 309 | wire [3:0] stage2_1 [0:7]; 310 | 311 | wire [3:0] stage3_0 [0:7]; 312 | wire [3:0] stage3_1 [0:7]; 313 | wire [3:0] stage3_2 [0:7]; 314 | 315 | 316 | //------------------------------------------------------------------------ 317 | // Stage 0 has only one level of sorting 318 | //------------------------------------------------------------------------ 319 | comapre_and_swap u1 (data_in[0], data_in[1], stage1[1], stage1[0]); 320 | comapre_and_swap u2 (data_in[2], data_in[3], stage1[2], stage1[3]); 321 | comapre_and_swap u3 (data_in[4], data_in[5], stage1[5], stage1[4]); 322 | comapre_and_swap u4 (data_in[6], data_in[7], stage1[6], stage1[7]); 323 | 324 | //------------------------------------------------------------------------ 325 | //Stage 1 has 2 levels of sorting 326 | //------------------------------------------------------------------------ 327 | comapre_and_swap u5 (stage1[0], stage1[2], stage2_0[2], stage2_0[0]); 328 | comapre_and_swap u6 (stage1[1], stage1[3], stage2_0[3], stage2_0[1]); 329 | comapre_and_swap u7 (stage1[4], stage1[6], stage2_0[4], stage2_0[6]); 330 | comapre_and_swap u8 (stage1[5], stage1[7], stage2_0[5], stage2_0[7]); 331 | 332 | comapre_and_swap u9 (stage2_0[0], stage2_0[2], stage2_1[2], stage2_1[0]); 333 | comapre_and_swap u10 (stage2_0[1], stage2_0[3], stage2_1[3], stage2_1[1]); 334 | comapre_and_swap u11 (stage2_0[4], stage2_0[6], stage2_1[4], stage2_1[6]); 335 | comapre_and_swap u12 (stage2_0[5], stage2_0[7], stage2_1[5], stage2_1[7]); 336 | 337 | //------------------------------------------------------------------------ 338 | // Stage 2 has 3 levels of sorting 339 | //------------------------------------------------------------------------ 340 | comapre_and_swap u13 (stage2_1[0], stage2_1[4], stage3_0[4], stage3_0[0]); 341 | comapre_and_swap u14 (stage2_1[1], stage2_1[5], stage3_0[5], stage3_0[1]); 342 | comapre_and_swap u15 (stage2_1[2], stage2_1[6], stage3_0[6], stage3_0[2]); 343 | comapre_and_swap u16 (stage2_1[3], stage2_1[7], stage3_0[7], stage3_0[3]); 344 | 345 | comapre_and_swap u17 (stage3_0[0], stage3_0[2], stage3_1[2], stage3_1[0]); 346 | comapre_and_swap u18 (stage3_0[1], stage3_0[3], stage3_1[3], stage3_1[1]); 347 | comapre_and_swap u19 (stage3_0[4], stage3_0[6], stage3_1[6], stage3_1[4]); 348 | comapre_and_swap u20 (stage3_0[5], stage3_0[7], stage3_1[7], stage3_1[5]); 349 | 350 | comapre_and_swap u21 (stage3_1[0], stage3_1[1], stage3_2[1], stage3_2[0]); 351 | comapre_and_swap u22 (stage3_1[2], stage3_1[3], stage3_2[3], stage3_2[2]); 352 | comapre_and_swap u23 (stage3_1[4], stage3_1[5], stage3_2[5], stage3_2[4]); 353 | comapre_and_swap u24 (stage3_1[6], stage3_1[7], stage3_2[7], stage3_2[6]); 354 | 355 | // Sorted data is assigned to output 356 | assign data_sort = stage3_2; 357 | 358 | endmodule 359 | ``` 360 | 361 | [![Run on EDA](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_run-on-eda-playground.png)](https://www.edaplayground.com/x/9JEa) 362 | 363 | The information found here was referred from an outstanding paper [Low-Cost Sorting Network Circuits Using Unary Processing](https://ieeexplore.ieee.org/document/8338366) 364 | 365 | Additional information about sorting networks can be found [here](http://staff.ustc.edu.cn/~csli/graduate/algorithms/book6/chap28.htm) and [here](http://www.cs.kent.edu/~batcher/sort.pdf) 366 | 367 | [![go_back](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_go_back.png)](#contents) 368 | 369 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 370 | 371 | ## D flip flop 372 | 373 | ![dff](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/dff.png) 374 | 375 | Verilog code for D flip-flop with active-high synchronous reset - 376 | 377 | ```verilog 378 | module dff (input d, clk, srst, 379 | output reg Q); 380 | always @ (posedge clk) begin 381 | if (srst) 382 | Q <= 1'b0; 383 | else 384 | Q <= d; 385 | end 386 | endmodule 387 | ``` 388 | 389 | 390 | Verilog code for D flip-flop with active-low asynchronous reset - 391 | 392 | ```verilog 393 | module dff (input D, clk, arst, 394 | output reg Q); 395 | always @ (posedge clk or negedge arst) begin 396 | if (~arst) 397 | Q <= 1'b0; 398 | else 399 | Q <= D; 400 | end 401 | endmodule 402 | ``` 403 | 404 | 405 | Verilog code for D flip-flop with active-low asynchronous reset - 406 | 407 | ```verilog 408 | module dff (input D, clk, arst, srst 409 | output reg Q); 410 | always @ (posedge clk or negedge arst) begin 411 | if (~arst) 412 | Q <= 1'b0; 413 | else if (srst) 414 | Q <= 1'b0; 415 | else 416 | Q <= D; 417 | end 418 | endmodule 419 | ``` 420 | 421 | [![go_back](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_go_back.png)](#contents) 422 | 423 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 424 | 425 | ## Serial in parallel out (SIPO) 426 | 427 | Typically in a Serial in Parallel out circuit, there are as many flops as the size of the parallel out. The input data is shifted in with clk and when all the data bits are available, the serially loaded data is read through the parallel port. 428 | 429 | Here, say we have 8-bit parallel port, so it takes 8 clk cycles to serially load 8-bits of data and the data is available for 1 clock cycle and then new data starts coming in resulting in the output being stable for only 1 clock cycle. 430 | 431 | ![sipo_basic](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/SIPO/sipo_basic.png) 432 | 433 | Figure 1: Basic serial-in-parallel-out circuit 434 | 435 | ```verilog 436 | module sipo_1 (input load, clk, rst, 437 | input data_in, 438 | output [7:0] data_out); 439 | 440 | // SIPO register array to read and shift data 441 | reg [7:0] data_reg; 442 | 443 | always @ (posedge clk or negedge rst) begin 444 | if (~rst) 445 | data_reg <= 8'h00; // Reset SIPO register on reset 446 | else if (load) 447 | data_reg <= {data_in, data_reg[7:1]}; // Load data to the SIPO register by right shifts 448 | end 449 | 450 | // Assign the SIPO register data to data_out wires 451 | assign data_out = data_reg; 452 | 453 | endmodule 454 | ``` 455 | 456 | If there is a need to keep the output data stable until we have the next valid data, we need to use a 2-step architecture as shown below. The data is clocked in to the serial registers at the serial_clk then when valid data is loaded, the serial_clk and parallel_clk are asserted together. This way the data loaded into the output registers stay constant until the next valid data is loaded serially. 457 | 458 | ![sipo_capture_reg](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/SIPO/sipo_capture_reg.png) 459 | 460 | Figure 2: Serial-in-parallel-out circuit with capture register 461 | 462 | ```verilog 463 | module sipo_2 (input load, clk, rst, 464 | input data_in, 465 | output reg [7:0] data_out); 466 | 467 | // SIPO register array to read and shift data 468 | reg [7:0] data_reg; 469 | 470 | always @ (posedge clk or negedge rst) begin 471 | if (~rst) begin 472 | data_reg <= 8'h00; // Reset SIPO register on reset 473 | data_out <= 8'h00; // Reset capture register 474 | end 475 | else begin 476 | if (load) 477 | data_reg <= {data_in, data_reg[7:1]}; // Load data to the SIPO register by right shifts 478 | else 479 | data_out <= data_reg; // Assign SIPO register data to capture register 480 | end 481 | end 482 | 483 | endmodule 484 | ``` 485 | 486 | [![go_back](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_go_back.png)](#contents) 487 | 488 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 489 | 490 | ## Parallel in serial out (PISO) 491 | 492 | Parallel-in serial-out is a one of the basic elements of ***serializer-deserializer (SerDes) circuits***. The PISO allows the parallel loading of data following which the data can be shifted out serially from either the MSB or the LSB side. This is how a parallel to serial conversion takes place. 493 | 494 | ![piso_block](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/PISO/piso_block.png) 495 | 496 | To load the data we need as many flip-flops as the data width of the parallel loading, i.e., if the data width is 8 bits, we need 8 flip flops to store these 8 bits. To differentiate between a load or shift operation we need an additional input which can be multiplexed for indicating either shift and load. If the signal is 1 it indicates a load and if 0 a shift. 497 | 498 | ![piso_basic](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/PISO/piso.png) 499 | 500 | The loading can be be asynchronous needing a flip-flop with set/reset pins. However, here we will be looking at a circuit with synchronous loading and shifting of 4-bit data 501 | 502 | ```verilog 503 | module piso (input load, clk, rst, 504 | input [7:0] data_in, 505 | output reg data_out); 506 | 507 | // PISO register array to load and shift data 508 | reg [7:0] data_reg; 509 | 510 | always @ (posedge clk or negedge rst) begin 511 | if (~rst) 512 | data_reg <= 8'h00; // Reset PISO register array on reset 513 | else begin 514 | 515 | // Load the data to the PISO register array and reset the serial data out register 516 | if (load) 517 | {data_reg, data_out} <= {data_in, 1'b0}; 518 | // Shift the loaded data 1 bit right; into the serial data out register 519 | else 520 | {data_reg, data_out} <= {1'b0, data_reg[7:0]}; 521 | end 522 | end 523 | 524 | endmodule 525 | ``` 526 | 527 | [![go_back](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_go_back.png)](#contents) 528 | 529 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 530 | 531 | ## Counters 532 | 533 | ### Synchronous counter 534 | 535 | ### Asynchronous/Ripple counter 536 | 537 | ### Ring counter 538 | 539 | ### Johnson counter 540 | 541 | ### Sequence counter 542 | 543 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 544 | 545 | ## MOD-N Counters 546 | 547 | ### MOD-3 counter 548 | 549 | ### MOD-5 counter 550 | 551 | ### MOD-6 counter 552 | 553 | ### MOD-7 counter 554 | 555 | ### MOD-8 counter 556 | 557 | ### MOD-9 counter 558 | 559 | ### MOD-11 counter 560 | 561 | ### MOD-12 counter 562 | 563 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 564 | 565 | ## Gray counter 566 | 567 | The gray code is a type of binary number ordering such that each number differes from its previous and the following number by exactly 1-bit. Gray codes are used in cases when the binary numbers transmitted by a digital system may result in a fault or ambuiguity or for implementing error corrections. 568 | 569 | The most simple implementation of a gray code counter will be a binary counter followed by a ***binary to gray*** converter. However, the datapath is huge resulting in a very low clock frequency. This is a good motive to pursue a design to implement a gray counter with a smaller datapath. 570 | 571 | ![gray_counter_circuit](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Gray_Counter/gray_counter_basic.png) 572 | 573 | Consider a 4-bit gray code `gray[3:0]` in the following table. 574 | 575 | ![gray_code_table](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Gray_Counter/gray_code_table.png) 576 | 577 | The ***count*** column gives the decimal value for the corrseponding gray code, ***gray[3:0]*** represent the binary encoded gray code, and ***gray[-1]*** is a place-holder and used to actually implement the gray code counter. 578 | 579 | From the table the following observations can be made - 580 | 1. ***gray[-1]*** flips every clock cycle, and is preset to `1'b1` 581 | 2. ***gray[0]*** flips everytime `gray[-1] == 1` 582 | 3. ***gray[1]*** flips everytime `(gray[0] == 1) & (gray[-1] == 0)` 583 | 4. ***gray[2]*** flips everytime `(gray[1] == 1) & (gray[0] == 0) & (gray[-1] == 0)` 584 | 5. ***gray[3]*** flips twice for a cycle which means we need additional condition to account for this. It flips when and `(gray[3] == 1) or (gray[2] == 0)` and `(gray[1] == 0) & (gray[0] == 0) & (gray[-1] == 0)` 585 | 586 | The ***red arrow*** in the table shows the bit getting flipped and the highlighed bits show the condition for the flip. 587 | 588 | The same has been shown here in the following circuit. ***gray[3:-1]*** is represented by the flip-flops and the logic when these flip make up the combinational logic. 589 | 590 | ![gray_counter_circuit1](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Gray_Counter/gray_counter.png) 591 | 592 | ```verilog 593 | module gray_counter(input clk, rst, 594 | output [3:0] gray_count); 595 | 596 | // D flip flops to store the gray count and the placeholder value 597 | reg [3:-1] q; 598 | 599 | // register declaration for combinational logic 600 | reg all_zeros_below[2:-1]; 601 | 602 | // Combinational logic to compute if the value below any bit of the gray count is 0 603 | always @ (*) begin 604 | all_zeros_below[-1] = 1; 605 | for (integer i = 0; i<3; i= i+1) begin 606 | all_zeros_below[i] = all_zeros_below[i-1] & ~q[i-1]; 607 | end 608 | end 609 | 610 | always @ (posedge clk) begin 611 | if (rst) q[3:-1] <= 5'b0000_1; 612 | 613 | else begin 614 | // The placegolder value toggles every clock 615 | q[-1] <= ~q[-1]; 616 | 617 | // The bits [n-1:0] toggle everytime the sequence below it is 1 followed by all zeros (1000...) 618 | for (integer i = 0; i<3; i= i+1) begin 619 | q[i] <= (q[i-1] & all_zeros_below[i-1]) ? ~q[i] : q[i]; 620 | end 621 | 622 | // The MSB flips when either the nth/(n-1)th bit is 1 followed by all zeros (X1000... or 1X000...) 623 | q[3] <= ((q[3] | q[2]) & all_zeros_below[2]) ? ~q[3] : q[3]; 624 | end 625 | end 626 | 627 | // The flip flop value is connected to the gray counter output. 628 | assign gray_count = q[3:0]; 629 | 630 | endmodule 631 | ``` 632 | 633 | [![Run on EDA](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_run-on-eda-playground.png)](https://www.edaplayground.com/x/Q6Zk) 634 | 635 | ![gray_counter_wave](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Gray_Counter/gray_counter_wave.png) 636 | 637 | [![go_back](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_go_back.png)](#contents) 638 | 639 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 640 | 641 | ## Fibonacci counter 642 | 643 | The Fibonacci numbers together form a fibonacci sequence, `F(n)`, such that each number is the sum of the two preceding ones, starting from 0 and 1 644 | 645 | i.e., `F(0) = 0`, `F(1) = 1` 646 | 647 | and `F(n) = F(n-1) + F(n-1)` for all `n > 2` 648 | 649 | The Fibonacci sequence thus becomes, `0, 1, 1, 2, 3, 5, 8, 13, 21, ....` 650 | 651 | The fibonacci numbers are used in various [computational applications](https://www.quora.com/What-are-the-practical-applications-of-Fibonacci-other-than-used-to-teach-programming) involving hardware: 652 | - Pseudorandom number generators 653 | - Determining the greatest common divisor 654 | - A one-dimensional optimization method, called the Fibonacci search technique 655 | - The Fibonacci number series is used for optional lossy compression 656 | 657 | Instead of performing the fibonacci computation using software which consumes a lot of time it is easier to faster to implement the fibonacci counter in hardware. 658 | 659 | Fibonacci Counter can be implemented in hardware with two registers A and B to store the initial numbers in the series, i.e., A = 1 and B = 0. The sum of the both A and B can be stored in A and the value in A can be moved into B and register B is used as the output. However, in the 2 register format, after reset we don't see the initial sequence number '0'. This can be resolved by adding a register C in series. The same is shown in the following waveform and schematic. 660 | 661 | ![fibonacci_counter](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Fibonacci/fibonacci_counter.png) 662 | 663 | The same can be implemented in verilog as - 664 | 665 | ```verilog 666 | module fibC (input clk, rst, 667 | output [3:0] out); 668 | 669 | // Registers to store the current and previous values of the fibonacci counter 670 | reg [3:0] RegA, RegB, RegC; 671 | 672 | always @ (posedge clk) begin 673 | if (rst) begin 674 | RegA <= 4'h1; // Start RegA with the second value of fibonacci series - '1' 675 | RegB <= 4'h0; // Start RegB with the first value of fibonacci series - '0' 676 | RegC <= 4'h0; // Reset RegC to '0' 677 | end 678 | else begin 679 | RegA <= RegB[3] ? 4'h1 : RegA + RegB; // if RegB == 8, reset RegA 680 | RegB <= RegB[3] ? 4'h0 : RegA; // if RegB == 8, reset RegB 681 | RegC <= RegB; // RegC is a synchronization register 682 | end 683 | end 684 | 685 | // Only one of the following two lines should be uncommented 686 | 687 | assign out = RegB; // To ignore the '0' at the startup after reset, uncomment this line 688 | //assign out = RegC; // To start with a '0' at startup after reset, uncomment this line 689 | 690 | endmodule 691 | ``` 692 | 693 | [![Run on EDA](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_run-on-eda-playground.png)](https://www.edaplayground.com/x/An9k) 694 | 695 | ![fib_counter_wave](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Fibonacci_Counter/gray_counter_wave.png) 696 | 697 | [![go_back](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_go_back.png)](#contents) 698 | 699 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 700 | 701 | ## Frequency Dividers 702 | 703 | Frequency divider is any curcuit that divides the frequency of the input signal, say `f` by a factor `n`, such that the frequency of the output signal is `f/n`. The frequency dividers with uneven pulse widths are very simple to be implemented with the use of counters and mod-n counters discussed earlier. However, we need additional circuitry to create a frequency divider with ***50% duty cycle***. 704 | 705 | Here, all the following frequency dividers have integer dividers `n = 1,2,3,4,5....` and have a ***50% duty cycle***. 706 | 707 | [![Run on EDA](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_run-on-eda-playground.png)](https://www.edaplayground.com/x/DMiK) 708 | 709 | ### Divide by 2 710 | 711 | The most basic a 1-bit counter also doubles up as a divide-by-2 circuit since for any given clock frequency, the output of the 1 bit counter is 1/2 the frequency of the cock signal. 712 | 713 | ![div_by_2](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Frequency_Dividers/div_by_2.png) 714 | 715 | The same can be modelled in verilog as: 716 | 717 | ```verilog 718 | module div_by_2 (input clk, rst, 719 | output clk_out); 720 | 721 | // Register to store the current count value 722 | reg Q; 723 | 724 | // State memory 725 | always @ (posedge clk) begin 726 | if (rst) 727 | Q <= 1'b0; // If reset, set Q to 0 728 | else 729 | Q <= ~Q; // If not reset, set Q to the next count value 730 | end 731 | 732 | // The clk/2 is set when Q == 1 733 | assign clk_out = Q; 734 | 735 | endmodule 736 | ``` 737 | 738 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 739 | 740 | ### Divide by 3 741 | 742 | To implement a divide by 3, we need to count to 3 and so we will need two flip-flops to count states `2'b00, 2'b01, 2'b10`. However since dividing factor is not equal to `2^n` we need additional flip-flops to get a 50% duty-cycle. We can achieve this by shifting the state ***Q[0]*** by 1/2 clock cycle and then ***OR***ing with ***Q[1]***. The 1/2 clock cycle shift is made by using a negative edge-triggered flip-flop. 743 | 744 | ![div_by_3_waveform](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Frequency_Dividers/div_by_3_waveform.png) 745 | 746 | Here, tp stands for ***time period of the clock***, i.e. ***+ 0.5 tp*** stands for the signal delayed by 0.5 clock period. 747 | 748 | The same can be modelled in verilog as: 749 | 750 | ```verilog 751 | module div_by_3 (input clk, rst, 752 | output clk_out); 753 | 754 | // Registers to store the current count value and wire to compute the next count value 755 | reg [1:0] Q, Q_next; 756 | 757 | // Register to delay Q[0] signal by 0.5 clock period 758 | reg Q_delay_0_5tp; 759 | 760 | // Combinational logic to compute the next state logic (count value) 761 | always @ (*) begin 762 | case(Q) 763 | 2'b00: Q_next = 2'b01; 764 | 2'b01: Q_next = 2'b10; 765 | 2'b10: Q_next = 2'b00; 766 | default: Q_next = 2'b00; 767 | endcase 768 | end 769 | 770 | // State memory 771 | always @ (posedge clk) begin 772 | if (rst) 773 | Q <= 2'h0; // If reset, set Q to 0 774 | else 775 | Q <= Q_next; // If not reset, set Q to the next count value 776 | end 777 | 778 | // Always block to delay Q[0] by 0.5 clock cycle 779 | always @ (negedge clk) begin 780 | if (rst) 781 | Q_delay_0_5tp <= 1'b0; 782 | else 783 | Q_delay_0_5tp <= Q[0]; 784 | end 785 | 786 | // The clk/3 is set when Q[0]_delayed_by_0.5_cycle == 1 or Q[1] == 1 787 | assign clk_out = Q_delay_0_5tp | Q[1]; 788 | 789 | endmodule 790 | ``` 791 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 792 | 793 | ### Divide by 4 794 | 795 | To implement a divide by 4, we need to count to 4 and so we will need two flip-flops to count states `2'b00, 2'b01, 2'b10, 2'b10`. We can use the state Q[1] as the output which has the frequency `fclk/4`. 796 | 797 | ![div_by_4](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Frequency_Dividers/div_by_4_waveform.png) 798 | 799 | ```verilog 800 | module div_by_4 (input clk, rst, 801 | output clk_out); 802 | 803 | // Registers to store the current count value and wire to compute the next count value 804 | reg [1:0] Q, Q_next; 805 | 806 | // Combinational logic to compute the next state logic (count value) 807 | always @ (*) begin 808 | case(Q) 809 | 2'b00: Q_next = 2'b01; 810 | 2'b01: Q_next = 2'b10; 811 | 2'b10: Q_next = 2'b11; 812 | 2'b11: Q_next = 2'b00; 813 | default: Q_next = 2'b00; 814 | endcase 815 | end 816 | 817 | // State memory 818 | always @ (posedge clk) begin 819 | if (rst) 820 | Q <= 2'h0; // If reset, set Q to 0 821 | else 822 | Q <= Q_next; // If not reset, set Q to the next count value 823 | end 824 | 825 | // The clk/4 is set when Q[1] == 1 826 | assign clk_out = Q[1]; 827 | 828 | endmodule 829 | ``` 830 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 831 | 832 | ### Divide by 5 833 | 834 | To implement a divide by 5, we need to count to 3 and so we will need 3 flip-flops to count states `2'b000, 2'b001, 2'b010, 2'b011, 2'b100`. However since dividing factor is not equal to `2^n` we need additional flip-flops to get a 50% duty-cycle. We can achieve this by shifting the state ***Q[1]*** by 1/2 clock cycle and then ***OR***ing with ***Q[2]***. The 1/2 clock cycle shift is made by using a negative edge-triggered flip-flop. 835 | 836 | ![div_by_5_table](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Frequency_Dividers/div_by_5_table.png) 837 | 838 | The table shows the current counter state and the next state. The first column shows the clock divider output. It must be noted the `0/1` and `1/0` refers to the signal changing from `0 -> 1` and `1 -> 0` respectively at the falling edge of the clock. 839 | 840 | ![div_by_5_waveform](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Frequency_Dividers/div_by_5_waveform.png) 841 | 842 | Here, tp stands for ***time period of the clock***, i.e. ***+ 0.5 tp*** stands for the signal delayed by 0.5 clock period. 843 | 844 | The same can be modelled in verilog as: 845 | 846 | ```verilog 847 | module div_by_5 (input clk, rst, 848 | output clk_out); 849 | 850 | // Registers to store the current count value and wire to compute the next count value 851 | reg [2:0] Q, Q_next; 852 | 853 | // Register to delay Q[1] signal by 0.5 clock period 854 | reg Q_delay_0_5tp; 855 | 856 | // Combinational logic to compute the next state logic (count value) 857 | always @ (*) begin 858 | if (Q == 3'd4) 859 | Q_next = 3'h0; // If counted to 4, set Q to 0 860 | else 861 | Q_next = Q + 1; // If not counted to 4, set Q to Q + 1 862 | end 863 | 864 | // State memory 865 | always @ (posedge clk) begin 866 | if (rst) 867 | Q <= 3'h0; // If reset, set Q to 0 868 | else 869 | Q <= Q_next; // If not reset, set Q to the next count value 870 | end 871 | 872 | // Always block to delay Q[1] by 0.5 clock cycle 873 | always @ (negedge clk) begin 874 | if (rst) 875 | Q_delay_0_5tp <= 1'b0; 876 | else 877 | Q_delay_0_5tp <= Q[1]; 878 | end 879 | 880 | // The clk/5 is set when Q[1]_delayed_by_0.5_cycle == 1 or Q[2] == 1 881 | assign clk_out = Q_delay_0_5tp | Q[2]; 882 | 883 | endmodule 884 | ``` 885 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 886 | 887 | ### Divide by 6 888 | 889 | To implement a divide by 6, we need to count to 6 and so we will need 3 flip-flops to count states `2'b000, 2'b001, 2'b010, 2'b011, 2'b100, 2'b101`. However since dividing factor is not equal to `2^n` we need additional flip-flops to get a 50% duty-cycle. We can achieve this by shifting the state ***Q[1]*** by 1 clock cycle and then ***OR***ing with ***Q[2]***. The 1 clock cycle shift is made by using a positive edge-triggered flip-flop. 890 | 891 | ![div_by_6_table](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Frequency_Dividers/div_by_6_table.png) 892 | 893 | The table shows the current counter state and the next state. The first column shows the clock divider output. 894 | 895 | ![div_by_6_waveform](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Frequency_Dividers/div_by_6_waveform.png) 896 | 897 | Here, tp stands for ***time period of the clock***, i.e. ***+ 1 tp*** stands for the signal delayed by 1 clock period. 898 | 899 | The same can be modelled in verilog as: 900 | 901 | ```verilog 902 | module div_by_6 (input clk, rst, 903 | output clk_out); 904 | 905 | // Registers to store the current count value and wire to compute the next count value 906 | reg [2:0] Q, Q_next; 907 | 908 | // Registers to delay Q[1] signal by 1 clock period 909 | reg Q_delay_1tp; 910 | 911 | 912 | // Combinational logic to compute the next state logic (count value) 913 | always @ (*) begin 914 | if (Q == 3'd5) 915 | Q_next = 3'h0; // If counted to 5, set Q to 0 916 | else 917 | Q_next = Q + 1; // If not counted to 5, set Q to Q + 1 918 | end 919 | 920 | // State memory 921 | always @ (posedge clk) begin 922 | if (rst) 923 | Q <= 3'h0; // If reset, set Q to 0 924 | else 925 | Q <= Q_next; // If not reset, set Q to the next count value 926 | end 927 | 928 | // Always block to delay Q[1] by 1 clock cycle 929 | always @ (posedge clk) begin 930 | if (rst) begin 931 | Q_delay_1tp <= 1'b0; 932 | end 933 | else begin 934 | Q_delay_1tp <= Q[1]; 935 | end 936 | end 937 | 938 | // The clk/6 is set when Q[1]_delayed_by_1_cycle == 1 or Q[2] == 1 939 | assign clk_out = Q_delay_1tp | Q[2]; 940 | 941 | endmodule 942 | ``` 943 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 944 | 945 | ### Divide by 9 946 | 947 | To implement a divide by 9, we need to count upto 9 and so we will need two flip-flops to count states `4'b0000, 4'b0001, .... 4'b0111, 4'b1000`. However since dividing factor is not equal to `2^n` we need additional flip-flops to get a 50% duty-cycle. We can achieve this by shifting the state ***Q[2]*** by 1/2 clock cycle and then ***OR***ing with ***Q[3]***. The 1/2 clock cycle shift is made by using a negative edge-triggered flip-flop. 948 | 949 | ![div_by_9_table](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Frequency_Dividers/div_by_9_table.png) 950 | 951 | The table shows the current counter state and the next state. The first column shows the clock divider output. It must be noted the `0/1` and `1/0` refers to the signal changing from `0 -> 1` and `1 -> 0` respectively at the falling edge of the clock. All other values change at the rising edge of the clock. 952 | 953 | ![div_by_9_waveform](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Frequency_Dividers/div_by_9_waveform.png) 954 | 955 | Here, tp stands for ***time period of the clock***, i.e. ***+ 0.5 tp*** stands for the signal delayed by 0.5 clock period. 956 | 957 | The same can be modelled in verilog as: 958 | 959 | ```verilog 960 | module div_by_9 (input clk, rst, 961 | output clk_out); 962 | 963 | // Registers to store the current count value and wire to compute the next count value 964 | reg [3:0] Q, Q_next; 965 | 966 | // Register to delay Q[2] signal by 0.5 clock period 967 | reg Q_delay_0_5tp; 968 | 969 | // Combinational logic to compute the next state logic (count value) 970 | always @ (*) begin 971 | if (Q == 4'd8) 972 | Q_next = 4'h0; // If counted to 8, set Q to 0 973 | else 974 | Q_next = Q + 1; // If not counted to 8, set Q to Q + 1 975 | end 976 | 977 | // State memory 978 | always @ (posedge clk) begin 979 | if (rst) 980 | Q <= 4'h0; // If reset, set Q to 0 981 | else 982 | Q <= Q_next; // If not reset, set Q to the next count value 983 | end 984 | 985 | 986 | // Always block to delay Q[2] by 1.5 clock cycle 987 | always @ (negedge clk) begin 988 | if (rst) 989 | Q_delay_0_5tp <= 1'b0; 990 | else 991 | Q_delay_0_5tp <= Q[2]; 992 | end 993 | 994 | // The clk/9 is set when Q[2]_delayed_by_0.5_cycle == 1 or Q[3] == 1 995 | assign clk_out = Q_delay_0_5tp | Q[3]; 996 | 997 | endmodule 998 | ``` 999 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1000 | 1001 | ### Divide by 11 1002 | 1003 | To implement a divide by 11, we need to count upto 11 and so we will need two flip-flops to count states `4'b0000, 4'b0001, .... 4'b1001, 4'b1010`. However since dividing factor is not equal to `2^n` we need additional flip-flops to get a 50% duty-cycle. We can achieve this by shifting the state ***Q[2]*** by 1.5 clock cycles and then ***OR***ing with ***Q[3]***. The 1.5 clock cycle shift is made by using a positive edge-triggered flip flop followed by a negative edge-triggered flip-flop. 1004 | 1005 | ![div_by_11_table](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Frequency_Dividers/div_by_11_table.png) 1006 | 1007 | The table shows the current counter state and the next state. The first column shows the clock divider output. It must be noted the `0/1` and `1/0` refers to the signal changing from `0 -> 1` and `1 -> 0` respectively at the falling edge of the clock. All other values change at the rising edge of the clock. 1008 | 1009 | ![div_by_11_waveform](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Frequency_Dividers/div_by_11_waveform.png) 1010 | 1011 | Here, tp stands for ***time period of the clock***, i.e. ***+ 1.5 tp*** stands for the signal delayed by 1.5 clock periods. 1012 | 1013 | The same can be modelled in verilog as: 1014 | 1015 | ```verilog 1016 | module div_by_11 (input clk, rst, 1017 | output clk_out); 1018 | 1019 | // Registers to store the current count value and wire to compute the next count value 1020 | reg [3:0] Q, Q_next; 1021 | 1022 | // Register to delay Q[2] signal by 1 clock period 1023 | reg Q_delay_1tp; 1024 | 1025 | // Register to delay Q[2] signal by 1.5 clock period 1026 | reg Q_delay_1_5tp; 1027 | 1028 | // Combinational logic to compute the next state logic (count value) 1029 | always @ (*) begin 1030 | if (Q == 4'd10) 1031 | Q_next = 4'h0; // If counted to 10, set Q to 0 1032 | else 1033 | Q_next = Q + 1; // If not counted to 10, set Q to Q + 1 1034 | end 1035 | 1036 | // State memory 1037 | always @ (posedge clk) begin 1038 | if (rst) 1039 | Q <= 4'h0; // If reset, set Q to 0 1040 | else 1041 | Q <= Q_next; // If not reset, set Q to the next count value 1042 | end 1043 | 1044 | // Always block to delay Q[2] by 1 clock cycle 1045 | always @ (posedge clk) begin 1046 | if (rst) 1047 | Q_delay_1tp <= 1'b0; 1048 | else 1049 | Q_delay_1tp <= Q[2]; 1050 | end 1051 | 1052 | // Always block to delay Q[2] by 1.5 clock cycle 1053 | always @ (negedge clk) begin 1054 | if (rst) 1055 | Q_delay_1_5tp <= 1'b0; 1056 | else 1057 | Q_delay_1_5tp <= Q_delay_1tp; 1058 | end 1059 | 1060 | // The clk/11 is set when Q[2]_delayed_by_1.5_cycle == 1 or Q[3] == 1 1061 | assign clk_out = Q_delay_1_5tp | Q[3]; 1062 | 1063 | endmodule 1064 | ``` 1065 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1066 | 1067 | ### Divide by 12 1068 | 1069 | To implement a divide by 12, we need to count upto 12 and so we will need two flip-flops to count states `4'b0000, 4'b0001, .... 4'b1010, 4'b1011`. However since dividing factor is not equal to `2^n` we need additional flip-flops to get a 50% duty-cycle. We can achieve this by shifting the state ***Q[2]*** by 2 clock cycles and then ***OR***ing with ***Q[3]***. The 1/2 clock cycle shift is made by using a 2 positive edge-triggered flip-flops in series. 1070 | 1071 | ![div_by_12_table](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Frequency_Dividers/div_by_12_table.png) 1072 | 1073 | The table shows the current counter state and the next state. The first column shows the clock divider output. 1074 | 1075 | ![div_by_12_waveform](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Frequency_Dividers/div_by_12_waveform.png) 1076 | 1077 | Here, tp stands for ***time period of the clock***, i.e. ***+ 2 tp*** stands for the signal delayed by 2 clock periods. 1078 | 1079 | The same can be modelled in verilog as: 1080 | 1081 | ```verilog 1082 | module div_by_12 (input clk, rst, 1083 | output clk_out); 1084 | 1085 | // Registers to store the current count value and wire to compute the next count value 1086 | reg [3:0] Q, Q_next; 1087 | 1088 | // Registers to delay Q[2] signal by 2 clock period 1089 | reg Q_delay_1tp, Q_delay_2tp; 1090 | 1091 | 1092 | // Combinational logic to compute the next state logic (count value) 1093 | always @ (*) begin 1094 | if (Q == 4'd11) 1095 | Q_next = 4'h0; // If counted to 11, set Q to 0 1096 | else 1097 | Q_next = Q + 1; // If not counted to 11, set Q to Q + 1 1098 | end 1099 | 1100 | // State memory 1101 | always @ (posedge clk) begin 1102 | if (rst) 1103 | Q <= 4'h0; // If reset, set Q to 0 1104 | else 1105 | Q <= Q_next; // If not reset, set Q to the next count value 1106 | end 1107 | 1108 | // Always block to delay Q[2] by 2 clock cycle 1109 | always @ (posedge clk) begin 1110 | if (rst) begin 1111 | Q_delay_1tp <= 1'b0; 1112 | Q_delay_2tp <= 1'b0; 1113 | end 1114 | else begin 1115 | Q_delay_1tp <= Q[2]; 1116 | Q_delay_2tp <= Q_delay_1tp; 1117 | end 1118 | end 1119 | 1120 | // The clk/12 is set when Q[2]_delayed_by_2_cycle == 1 or Q[3] == 1 1121 | assign clk_out = Q_delay_2tp | Q[3]; 1122 | 1123 | endmodule 1124 | ``` 1125 | 1126 | [![go_back](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_go_back.png)](#contents) 1127 | 1128 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1129 | 1130 | ## Linear Feedback Shift Register (LFSR) 1131 | 1132 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1133 | 1134 | ## Sequence Detector 1135 | 1136 | A simple sequence detector can be modelled in several ways - 1137 | 1. Non-overlapping - Here, consider a sequence detector for sequence 1010. For the input sequence `10101010` the output will be `00010001`, i.e. the sequence is detected in a non-overlapping fashion. Once a sequence is detected, the sequence needs to be repeated completely from the start to be dected again. 1138 | 2. Overlapping - Again, consider a sequence detector for sequence 1010. For the input sequence `10101010` the output will be `00010101`, i.e. the sequence is detected in an overlapping fashion. Once a sequence is detected, a new sequence can be detected using a part of the previously detected sequence when applicable. 1139 | 1140 | Also, the state machine being used to detect the sequence can be mealy or a moore state machine. This will change the total number of states at some cost to the output functional logic 1141 | 1142 | ### Sequence Detector - 1010 1143 | 1144 | ![seqD_1010](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sequence_Detector/seqD_1010.png) 1145 | 1146 | Figure: Sequence Detector 1010 - Moore and Mealy; non-overlapping and overlapping state machines. 1147 | 1148 | ```verilog 1149 | // Code your design here 1150 | module seq_1010(input din, clk, rst, 1151 | output dout); 1152 | 1153 | // Parameterized state values for ease 1154 | parameter S0 = 0, S1 = 1, S2 = 2, S3 = 3, S4 = 4; 1155 | 1156 | // RState memory definition 1157 | reg [2:0] state, next_state; 1158 | 1159 | // Next State Logic - combinational logic to compute the next state based on the current state and input value 1160 | always @ (*) begin 1161 | case (state) 1162 | S0: next_state = din ? S1 : S0; 1163 | S1: next_state = din ? S1 : S2; 1164 | S2: next_state = din ? S3 : S0; 1165 | S3: next_state = din ? S1 : S4; 1166 | S4: next_state = din ? S1 : S0; // This transition for non-overlaping sequence detector (If uncommented, comment the next line) 1167 | //S4: next_state = din ? S3 : S0; // This transition for overlaping sequence detector (If uncommented, comment the previous line) 1168 | default: next_state = S0; 1169 | endcase 1170 | end 1171 | 1172 | // State Memory - Assign the computed next state to the state memory on the clock edge 1173 | always @ (posedge clk) begin 1174 | if (rst) state <= 3'b000; 1175 | else state <= next_state; 1176 | end 1177 | 1178 | // Output functional logic - The states for which the output should be '1' 1179 | assign dout = state == S4; 1180 | endmodule 1181 | ``` 1182 | 1183 | [![Run on EDA](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_run-on-eda-playground.png)](https://www.edaplayground.com/x/iK_p) 1184 | 1185 | ![moore_1010_wave1](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sequence_Detector/moore_1010_non_overlap.png) 1186 | 1187 | Figure: Sequence Detector 1010 - Moore non-overlapping waveform. 1188 | 1189 | 1190 | ![moore_1010_wave2](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sequence_Detector/moore_1010_overlap.png) 1191 | 1192 | Figure: Sequence Detector 1010 - Moore overlapping waveform. 1193 | 1194 | 1195 | ```verilog 1196 | // Code your design here 1197 | module seq_1010(input din, clk, rst, 1198 | output reg dout); 1199 | 1200 | // Parameterized state values for ease 1201 | parameter S0 = 0, S1 = 1, S2 = 2, S3 = 3; 1202 | 1203 | // RState memory definition 1204 | reg [1:0] state, next_state; 1205 | 1206 | // Next State Logic - combinational logic to compute the next state based on the current state and input value 1207 | always @ (*) begin 1208 | case (state) 1209 | S0: next_state = din ? S1 : S0; 1210 | S1: next_state = din ? S1 : S2; 1211 | S2: next_state = din ? S3 : S0; 1212 | S3: next_state = din ? S1 : S0;// This transition for non-overlaping sequence detector (If uncommented, comment the next line) 1213 | //S3: next_state = din ? S1 : S2; // This transition for overlaping sequence detector (If uncommented, comment the previous line) 1214 | default: next_state = S0; 1215 | endcase 1216 | end 1217 | 1218 | // State Memory - Assign the computed next state to the state memory on the clock edge 1219 | always @ (posedge clk) begin 1220 | if (rst) state <= 2'b00; 1221 | else state <= next_state; 1222 | end 1223 | 1224 | // Output functional logic - The states for which the output should be '1' 1225 | always @ (posedge clk) begin 1226 | if (rst) dout <= 1'b0; 1227 | else begin 1228 | if (~din & (state == S3)) dout <= 1'b1; 1229 | else dout <= 1'b0; 1230 | end 1231 | end 1232 | endmodule 1233 | ``` 1234 | 1235 | [![Run on EDA](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_run-on-eda-playground.png)](https://www.edaplayground.com/x/HbJV) 1236 | 1237 | ![mealy_1010_wave1](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sequence_Detector/mealy_1010_non_overlap.png) 1238 | 1239 | Figure: Sequence Detector 1010 - Mealy non-overlapping waveform. 1240 | 1241 | ![mealy_1010_wave2](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sequence_Detector/mealy_1010_overlap.png) 1242 | 1243 | Figure: Sequence Detector 1010 - Mealy overlapping waveform. 1244 | 1245 | The sequence can also be detected using a simple n-bit shift register, where "n" represents the length of the sequence to be detected (in this case 4) and a comparator can be used to check the state of these n-bit registers. However, consider a sequence which has 20 bits, then we will need a 20 bit shift register which happens to be extremely costly in terms of area. The same can be acheived using a state machine with just 5 flip-flops and some additional combinational logic. 1246 | 1247 | ![seqD_1010_shiftReg](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sequence_Detector/seqD_1010_shiftReg.png) 1248 | 1249 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1250 | 1251 | ### Sequence Detector - 1001 1252 | 1253 | ![seqD_1001](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sequence_Detector/seqD_1001.png) 1254 | 1255 | ```verilog 1256 | module seq_1001_moore (input din, clk, rst, 1257 | output dout); 1258 | 1259 | // Parameterized state values for ease 1260 | parameter S0 = 0, S1 = 1, S2 = 2, S3 = 3, S4 = 4; 1261 | 1262 | // RState memory definition 1263 | reg [2:0] state, next_state; 1264 | 1265 | // Next State Logic - combinational logic to compute the next state based on the current state and input value 1266 | always @ (*) begin 1267 | case (state) 1268 | S0: next_state = din ? S1 : S0; 1269 | S1: next_state = din ? S1 : S2; 1270 | S2: next_state = din ? S1 : S3; 1271 | S3: next_state = din ? S4 : S0; 1272 | S4: next_state = din ? S1 : S0; // This transition for non-overlaping sequence detector (If uncommented, comment the next line) 1273 | //S4: next_state = din ? S1 : S2; // This transition for overlaping sequence detector (If uncommented, comment the previous line) 1274 | default: next_state = S0; 1275 | endcase 1276 | end 1277 | 1278 | // State Memory - Assign the computed next state to the state memory on the clock edge 1279 | always @ (posedge clk) begin 1280 | if (rst) state <= 3'b000; 1281 | else state <= next_state; 1282 | end 1283 | 1284 | // Output functional logic - The states for which the output should be '1' 1285 | assign dout = state == S4; 1286 | endmodule 1287 | ``` 1288 | 1289 | [![Run on EDA](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_run-on-eda-playground.png)](https://www.edaplayground.com/x/9V9V) 1290 | 1291 | ![mealy_1001_wave1](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sequence_Detector/mealy_1010_non_overlap.png) 1292 | 1293 | Figure: Sequence Detector 1001 - Mealy non-overlapping waveform. 1294 | 1295 | ![mealy_1001_wave2](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sequence_Detector/mealy_1010_overlap.png) 1296 | 1297 | Figure: Sequence Detector 1001 - Mealy overlapping waveform. 1298 | 1299 | ```verilog 1300 | module seq_1001_mealy (input din, clk, rst, 1301 | output reg dout); 1302 | 1303 | // Parameterized state values for ease 1304 | parameter S0 = 0, S1 = 1, S2 = 2, S3 = 3; 1305 | 1306 | // RState memory definition 1307 | reg [2:0] state, next_state; 1308 | 1309 | // Next State Logic - combinational logic to compute the next state based on the current state and input value 1310 | always @ (*) begin 1311 | case (state) 1312 | S0: next_state = din ? S1 : S0; 1313 | S1: next_state = din ? S1 : S2; 1314 | S2: next_state = din ? S1 : S3; 1315 | S3: next_state = S0;// This transition for non-overlaping sequence detector (If uncommented, comment the next line) 1316 | //S3: next_state = din ? S1 : S0; // This transition for overlaping sequence detector (If uncommented, comment the previous line) 1317 | default: next_state = S0; 1318 | endcase 1319 | end 1320 | 1321 | // State Memory - Assign the computed next state to the state memory on the clock edge 1322 | always @ (posedge clk) begin 1323 | if (rst) state <= 2'b00; 1324 | else state <= next_state; 1325 | end 1326 | 1327 | // Output functional logic - The states for which the output should be '1' 1328 | always @ (posedge clk) begin 1329 | if (rst) dout <= 1'b0; 1330 | else begin 1331 | if (din & (state == S3)) dout <= 1'b1; 1332 | else dout <= 1'b0; 1333 | end 1334 | end 1335 | endmodule 1336 | ``` 1337 | 1338 | [![Run on EDA](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_run-on-eda-playground.png)](https://www.edaplayground.com/x/7VVS) 1339 | 1340 | ![mealy_1001_wave1](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sequence_Detector/mealy_1010_non_overlap.png) 1341 | 1342 | Figure: Sequence Detector 1001 - Mealy non-overlapping waveform. 1343 | 1344 | ![mealy_1001_wave2](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Sequence_Detector/mealy_1010_overlap.png) 1345 | 1346 | Figure: Sequence Detector 1001 - Mealy overlapping waveform. 1347 | 1348 | [![go_back](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_go_back.png)](#contents) 1349 | 1350 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1351 | 1352 | ## Register File 1353 | 1354 | Register File is a type of memory block (typically used in a CPU), a m-set of storage cells to store data n-bit wide. It is used to hold data and fetch data based on the need. To perform this function, the register has the ***write operation*** to enable writing data to the register locations and ***read operation*** to enable reading the register locations. To write and read data the register file has ***write pointer*** and ***read pointer*** inputs which can be in a binary encoded or one-hot coded fashion. The number of writes and reads that can be performed in a clock cycle decide the number of ***write port*** and ***read ports*** needed in a register file. 1355 | 1356 | The most common use of a register file is in a CPU in which we can perform a write to store the computed data and 2 reads to fetch data operands to operate on in a clock cycle. For this reason, we will design a register file with 1 write port and 2 read ports. 1357 | 1358 | At the transistor level, register file can be an array of flip flops. However, in larger designs this is costlier and it is implemented through SRAM cells. However, with an SRAM cell array there is additional considerations of read and write cycles. 1359 | 1360 | ![register_file](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Register_File/register_file.png) 1361 | 1362 | Figure: Register file with 1 write port and 2 read ports 1363 | 1364 | Register file operations include: 1365 | 1. ***Register File Read Operation:*** A ***read address*** value is provided on the ***read address port*** to select the register to be read from. The ***read data*** is available immediately through the mux coming out on the ***read data port***. 1366 | 2. ***Register File Write Operation:*** A ***write address*** value is provided on the ***write address port*** to select the register to which data is to be written and ***write data*** value is provided on the ***write data port*** which is the data to be written to. 1367 | 1368 | ```verilog 1369 | module RegisterFile ( input clk, srst, reg_write, 1370 | input [7:0] w_data, 1371 | input [2:0] r_addr1, r_addr2, w_addr, 1372 | output [7:0] r_data1, r_data2); 1373 | 1374 | // Register memory array - 8 locations of 8 bits each 1375 | reg [7:0] register [0:7]; 1376 | 1377 | integer i; 1378 | 1379 | always @ (posedge clk) begin 1380 | if (srst) begin 1381 | 1382 | // Initialize all registers to value 0 1383 | for(i = 0; i < 8; i=i+1) begin 1384 | register[i] <= 'h0; 1385 | end 1386 | end 1387 | else if (reg_write) 1388 | 1389 | // Write to registers only on condition reg_write 1390 | // On reg_write, write the data to the register address provided on w_addr 1391 | register[w_addr] <= w_data; 1392 | end 1393 | 1394 | // Read data available on 2 read ports based on 2 seperate read addresses 1395 | assign r_data1 = register[r_addr1]; 1396 | assign r_data2 = register[r_addr2]; 1397 | 1398 | endmodule 1399 | ``` 1400 | 1401 | [![Run on EDA](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_run-on-eda-playground.png)](https://www.edaplayground.com/x/hj7Y) 1402 | 1403 | ![reg_file_wave](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Register_File/reg_file_wave.png) 1404 | 1405 | [![go_back](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_go_back.png)](#contents) 1406 | 1407 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1408 | 1409 | ## First-in-first-out (FIFO) 1410 | 1411 | In this day, almost every digital component works on a clock and it is very common that the sub-systems exchange data for computational and operational needs. An intermediary becomes necessary if: 1412 | - The data produced and the data consumer operate on different clock frequencies 1413 | - If the data is being produced at a slower speed than the data is being consumed ***(f_write_clk < f_read_clk)*** the data transfer can take place through a single data register followed by asynchronous data synchronization methods (handshake or 2-clock synchronization) 1414 | - If the data is being produced at a higher speed than the data is being consumed ***(f_write_clk > f_read_clk)*** the data transfer needs buffering which can be implemented through an asynchronous FIFO. The depth of the FIFO depends the write and read clock and the maximum data burst length. 1415 | - The data producer and the data consumer have a skew between their clocks 1416 | - If the data is being produced at the same speed as the data is being consumed ***(f_write_clk = f_read_clk)*** and there is a skew between the producer and the consumer clock, the data can be transferred through a lock-up latch/register to overcome the skew 1417 | - There is a skew between the data production burst and data reception burst 1418 | - If the producer and consumer operate at the same clock but have a large skew between when a burst of data is produced and when the burst of data is consumed. In such scenario, the produced data needs to be buffered and the sequence of transfer needs to be preserved, then a synchronous FIFO can be used. The depth of such FIFO is decided by the maximum burst length 1419 | 1420 | 1421 | Additional information can be found at [FIFO Architecture, Functions, and Applications](https://www.ti.com/lit/an/scaa042a/scaa042a.pdf) 1422 | 1423 | Additional info on deciding the fifo depth can be found at [Calculation of FIFO Depth](https://hardwaregeeksblog.files.wordpress.com/2016/12/fifodepthcalculationmadeeasy2.pdf) 1424 | 1425 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1426 | 1427 | ### Synchronous FIFO 1428 | 1429 | ***Synchronous FIFO*** - The type of FIFOs which have common write and read clock are called synchronous FIFO. Synchronous FIFOs are very common in a processor/controller ICs which work on a common system clock. Since all the sub-systems work on the same system clock they can make use of sync-FIFOs with a possible need for skew handling. 1430 | 1431 | ![fifo_sync](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/FIFO/fifo_sync.png) 1432 | 1433 | ```verilog 1434 | module fifo(input clk, rst, wen, ren, 1435 | input [7:0] din, 1436 | output full, empty, 1437 | output reg [7:0] dout); 1438 | 1439 | // FIFO memory array - 8 locations of 8 bits each 1440 | reg [7:0] mem [0:7]; 1441 | 1442 | // FIFO write and read pointer registers (n+1) bit wide 1443 | reg [3:0] wptr, rptr; 1444 | 1445 | // read enable and write enable qualified signals declaration 1446 | wire wenq, renq; 1447 | 1448 | // Computation of full and empty signals based on the current 1449 | // read and qrite pointers 1450 | assign full = ((wptr ^ rptr) == 4'b1000); 1451 | assign empty = (wptr == rptr); 1452 | 1453 | // read enable qualified and write enable qualified are generated 1454 | // based on the write/read request and full and empty status of FIFO 1455 | assign wenq = ~full & wen; 1456 | assign renq = ~empty & ren; 1457 | 1458 | always @ (posedge clk) begin 1459 | 1460 | if (rst) begin 1461 | // Write and read pointers are initialized to 0 1462 | wptr <= 4'b0000; 1463 | rptr <= 4'b0000; 1464 | 1465 | // FIFO memory is initialized to 0 (not necessary) 1466 | for (integer i = 0; i < 8; i = i + 1) 1467 | mem[i] = 8'h00; 1468 | end 1469 | else begin 1470 | // Write pointer is incremented on valid write request 1471 | // FIFO memory is updated with data for valid write request 1472 | if (wenq) begin 1473 | wptr <= wptr + 1; 1474 | mem[wptr] <= din; 1475 | end 1476 | else begin 1477 | wptr <= wptr; 1478 | mem[wptr] <= mem[wptr[2:0]]; 1479 | end 1480 | 1481 | // Read pointer is incremented on valid read request 1482 | if (renq) 1483 | rptr <= rptr + 1; 1484 | else 1485 | rptr <= rptr; 1486 | end 1487 | end 1488 | 1489 | // Read data port 1490 | assign dout = mem[rptr[2:0]]; 1491 | 1492 | endmodule 1493 | ``` 1494 | 1495 | [![Run on EDA](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_run-on-eda-playground.png)](https://www.edaplayground.com/x/KpjL) 1496 | 1497 | ![fifo_sync_wave](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/FIFO/fifo_sync_wave.png) 1498 | 1499 | [![go_back](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_go_back.png)](#contents) 1500 | 1501 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1502 | 1503 | ### Synchronous FIFO with odd depth 1504 | 1505 | Typically, a FIFO has ***2^n*** locations and for such a FIFO a ***n+1*** bit write and read pointers are used. However, in a FIFO with odd depth, i.e., which has locations not equal to ***2^n*** we will continue to use a ***n+1*** bit write and read pointers but these will be implemented as a mod-n counter. 1506 | 1507 | For example, say we need to design a FIFO with 6 locations we need 4-bit read and write pointers of which the lower three bits will sequence from `3'b000, 3'b001, 3'b010, 3'b011, 3'b100, 3'b101` to point to the FIFO memory locations. 1508 | 1509 | The same can be modelled in verilog as, 1510 | 1511 | ```verilog 1512 | module FIFO(input clk, wen, ren, rst, 1513 | input [7:0] data_in, 1514 | output full, empty, 1515 | output [7:0] data_out); 1516 | 1517 | // FIFO write and read pointer registers (n+1) bit wide 1518 | reg [3:0] wptr, rptr; 1519 | 1520 | // FIFO memory array - 8 locations of 8 bits each 1521 | reg [7:0] mem [0:5]; 1522 | 1523 | // Computation of full and empty signals based on the current 1524 | // read and qrite pointers 1525 | assign full = (wptr ^ rptr) == 4'h8; 1526 | assign empty = wptr == rptr; 1527 | 1528 | // read enable qualified and write enable qualified are generated 1529 | // based on the write/read request and full and empty status of FIFO 1530 | assign wenq = ~full & wen; 1531 | assign renq = ~empty & ren; 1532 | 1533 | always @ (posedge clk) begin 1534 | if (rst) begin 1535 | // FIFO memory is initialized to 0 (not necessary) 1536 | for (integer i = 0; i < 8; i=i+1) 1537 | mem[i] <= 8'h00; 1538 | 1539 | // Write and read pointers are initialized to 0 1540 | wptr <= 4'h0; 1541 | rptr <= 4'h0; 1542 | end 1543 | else begin 1544 | // Write pointer is incremented on valid write request 1545 | // FIFO memory is updated with data for valid write request 1546 | if (wenq) begin 1547 | if (wptr[2:0] == 3'b101) 1548 | wptr <= {~wptr[3], 3'b000}; 1549 | else 1550 | wptr <= wptr+1; 1551 | mem[wptr[2:0]] <= datain; 1552 | end 1553 | 1554 | // Read pointer is incremented on valid read request 1555 | if (renq) begin 1556 | if (rptr[2:0] == 3'b101) 1557 | rptr <= {~rptr[3], 3'b000}; 1558 | else 1559 | rptr <= rptr+1; 1560 | end 1561 | end 1562 | end 1563 | 1564 | // Read data port 1565 | assign dataout = mem[rptr[2:0]]; 1566 | 1567 | endmodule 1568 | ``` 1569 | 1570 | [![Run on EDA](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_run-on-eda-playground.png)](https://www.edaplayground.com/x/Jmkw) 1571 | 1572 | [![go_back](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_go_back.png)](#contents) 1573 | 1574 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1575 | 1576 | ### Asynchronous FIFO 1577 | 1578 | ***Asynchronous FIFO*** - The type of FIFOs which have different write and read clock are called asynchronous FIFO. Such FIFO block is typically used when data needs to be transferred across clock-domain-crossing (CDC), where both the producer and the consumer work in different clock domain. 1579 | 1580 | [![Run on EDA](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_run-on-eda-playground.png)](https://www.edaplayground.com/x/fabv) 1581 | 1582 | [![go_back](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_go_back.png)](#contents) 1583 | 1584 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1585 | 1586 | ## Last in first out (LIFO) 1587 | 1588 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1589 | 1590 | ## Round robin arbiter 1591 | 1592 | [![go_back](https://raw.githubusercontent.com/sumukhathrey/Verilog/main/Docs/Images/button_go_back.png)](#contents) 1593 | 1594 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1595 | 1596 | # References 1597 | 1598 | 1599 | [Click here](https://www.chipverify.com/verilog/verilog-tutorial) to visit website with extensive documentation of verilog 1600 | 1601 | [Click here](http://www.eng.auburn.edu/~nelsovp/courses/elec4200/VHDL/Verilog_Overview_4200.pdf) to visit an exceptional compilation of basic verilog for ASIC design 1602 | 1603 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1604 | 1605 | # About and Contact Info 1606 | 1607 | Website Version: 1.08.054 1608 | --------------------------------------------------------------------------------