ECE 2411 - LAB 5.pdf - Todd Christiansen ECE 2411-001 LAB 5 DESIGN AND SIMULATE A BCD COUNTER OBJECTIVE The objective of this lab was to continue

ECE 2411 - LAB 5.pdf - Todd Christiansen ECE 2411-001 LAB 5...

This preview shows page 1 out of 7 pages.

Unformatted text preview: Todd Christiansen ECE 2411-001 LAB 5 – DESIGN AND SIMULATE A BCD COUNTER OBJECTIVE – The objective of this lab was to continue exploring applications of sequential circuit design in Verilog. We will apply our newfound knowledge of counters to design a modular BCD counter which has two digits and counts from 00 to 99. The counter must also have a parallel load function to hardcode a starting position, as well as a reset option to clear the entire counter. EQUIPMENT ModelSim PE Simulator PROCEDURE This lab involves the design of an 8-bit, two digit counter. This system can be built in a modular fashion, with two individual 4-bit BCD counters in series. The following figure shows the state diagram for a single BCD counter: Fig. 1 - State Diagram for 4-Bit BCD Counter In order to implement a single BCD counter which satisfies Figure 1 and the other conditions set by the lab, we can simply implement the form of a 4-bit binary counter with parallel load. This will include inputs for clk, load, reset, count, arrays for inData and outData, and one output for the carry digit. The carry output will be equal to 1 when the state of the counter is 1001. It will also check that count is still enabled and load is disabled with the || operator. The following code excerpt shows the conditional statement which generates the correct behavior for the BCD counter: always @ (posedge(clk), negedge(reset)) begin if (~reset || carry) outData <= 4'b0000; else if (load) outData <= inData; else if (count) outData <= outData + 1'b1; else outData <= outData; end Both a low-active reset and the carry output can trigger a response which will return the counter to 0. When load is enabled, the outData vector will be assigned the values of inData. If count is enabled instead, the counter will continue incrementing with each step. If neither is true, the counter will remain at the same value. Once the 4-Bit BCD counter is designed, two of these modules can be cascaded into a 2-digit BCD counter capable of counting from 00 to 99. The following block diagram shows the routing which is necessary for this system to function: Fig. 2 - Block Diagram for 00 to 99 BCD Counter System The consideration of LSB (least significant bit) and MSB (most significant bit) are essential in this system; the carry output of the LSB counter must drive the count function of the MSB counter. This way, every time the LSB moves from the highest value (9) to the lowest (0), it will increment the MSB. This accurately recreates a base -10 counting system with BCD encoding. Because this system will be contained in one verilog module, the input and output data signals can each be handled by a corresponding 8-element vector. When it comes time to simulate this system with a test bench, there are two trials that must be conducted to totally verify the modules: first, we must initialize the counter at 00 and observe it counting to 99 and repeating. Secondly, we must initialize the counter at the decimal value 51 using inData and load, then make sure that it still functions correctly. Once these two trials have been completed, we can definitively verify that the system is working. OBSERVATIONS / RESULTS The first trial, which initializes the BCD counter at 00 and counts repeatedly from 0 to 99, requires us to call an instantiation of the FullCounter module which is created with two cascaded 4-Bit BCD counters. Once this call is made, the counters can be cleared with reset, and the inData value and load set to 0 so that they have no chance of interfering with the counter. After all of these operations are taken care of, the count value is set to 1, and the counter is allowed to start incrementing for the duration of the simulation. The following figure shows the waveform results of this first trial: Fig. 3 - Waveform Overview for 0 to 99 Trial If an observer is familiar with digital systems, it should be clear that the above waveform is successfully incrementing from its lowest possible value to its highest possible value on repeat for the duration of the simulation. If this is not adequately clear from Figure 3, the following image shows a zoomed view of the point where the counter transitions from 99 back to 00: Fig. 4 - Region of Simulation Where Output Returns from 99 to 00 For the second trial, the inData value must be set to 51 (01010001 in BCD), then passed to the counter via the load enable. The following image shows the initial period of the simulation, as the variables are set and the counting is initialized: Fig. 5 - Initial Region of Trial 2, inData = 51 The next figure shows the simulation from the beginning of the count, initializing at 51: Fig. 6 - Counting Region of Trial 2, inData = 55 Finally, we must examine the region where 99 returns back to 00, to make sure that the counter still functions correctly when inData is used to load an initial value. The following figure shows this region, and verifies that the counter is still repeating as expected: Fig. 7 - Turnover Region of Trial 2, inData = 55 As can be observed from Figures 5 - 7, the 2-digit BCD counter still functions correctly when loaded with an initial value. Its incrementation remains the same, as well as its ability to return from 99 to 00, and stay within the defined limits of the project. CONCLUSION I ran into a series of difficulties when trying to design the 2-digit BCD counter. For my basic model of a 4-bit binary counter with parallel notes, I used the example from Dr Qin’s notes. However, I had to rework the design of the reset effect, since the counter was going to be used in a cascaded system. Instead of simply using the reset input, I initially used the || operator with a value of 4’b1001 for the clear condition. This way, if the BCD counter was equal to 9, it would return to 0 on the next iteration. This implementation created problems, since the cascaded system would often reset before reaching 9. When I tried to use 10 as the clear value with an immediate reassignment, the simulation had a number of strange alphanumeric values that diverged from the normal decimal sequence. Ultimately, I used the output of carry as the trigger for clearing the counter, because it checked more precisely for the end of the counter than just a certain binary output. The construction of the cascaded system was very simple once I corrected implementation issues in the individual BCD counter module. All it required was two instantiations of the BCD counter module, and a connection of the LSB’s carry to the MSB’s count. The testbench was similarly straightforward; the only issue I encountered here was loading the inData values. I initially attempted to use a decimal input, and allowed inData to interpret it as binary. However, this resulted in incorrect values, and I could not discern why the data was not being read correctly. Ultimately, I changed the initialization to BCD form, and obtained the correct input values. The code for all of the modules involved in this project can be found in the appendix, which starts on the following page. APPENDIX 4-BIT BCD COUNTER module BinaryCounter4Bit(clk, reset, count, load, inData, outData, carry); input clk, reset, count, load; input [3:0] inData; output reg [3:0] outData; output carry; assign carry = count && (~load) && (outData == 4'b1001); always @ (posedge(clk), negedge(reset)) begin if (~reset || carry) outData <= 4'b0000; else if (load) outData <= inData; else if (count) outData <= outData + 1'b1; else outData <= outData; end endmodule FULL COUNTING SYSTEM module FullCounter (input clk, reset, count, load, input [7:0] inData, output [7:0] outData); wire carryBit; BinaryCounter4Bit LSB (clk, reset, count, load, inData[3:0], outData[3:0], carryBit); BinaryCounter4Bit MSB (clk, reset, carryBit, load, inData[7:4], outData[7:4], carry); endmodule BCD COUNTER TESTBENCH `timescale 1ns/1ns module CounterTestBench(); reg clk, reset, count, load; reg [7:0] inData; wire [7:0] outData; FullCounter A1 (clk, reset, count, load, inData, outData); initial #1000 $stop; initial begin clk = 0; forever #1 clk = ~clk; end initial fork inData = 0; reset = 0; #1 reset = 1; #3 inData = 8'b01010001; #5 load = 1; #10 load = 0; #15 inData = 0; #20 count = 1; join endmodule ...
View Full Document

  • Left Quote Icon

    Student Picture

  • Left Quote Icon

    Student Picture

  • Left Quote Icon

    Student Picture