• No results found

Combinational Examples

9.2 Tomorrow Circuit

In Section 1.5 we introduced a calendar circuit. The key module of this circuit was a tomorrow circuit that given today’s date in month, month, day-of-week format computes tomorrow’s date in the same format. In this section we present the Verilog implementation of this tomorrow circuit.

A key step in designing a digital circuit is dividing a large problem into simpler subproblems. We can then design simple modules to solve these sub-problems and compose these modules to solve our larger problem. For the tomorrow circuit we can define two subproblems:

1. Increment the day of the week. This is completely independent of the month or day of the month.

2. Determine the number of days in the current month.

//---// Multiple_of_3_bit

// Cell for iterative multiple of 3 circuit.

// Determines the remainder (mod 3) of the number from this bit to the MSB.

// Input:

// in - the current bit of the number being checked

// remin - the remainder after the last bit checked (2 bits) // Output:

// remout - the remainder after checking this bit (2 bits).

//

// remin has weight 2 since its from the bit to the left, thus {remin, in}

// forms a 3 bit number. We divide this number by 3 and produce the remainder // on remout.

//---module Multiple_of_3_bit(in, remin, remout) ;

input in ;

input [1:0] remin ; output [1:0] remout ; reg [1:0] remout ;

always @(in, remin) begin case({remin, in})

3’d0: remout = 0 ; 3’d1: remout = 1 ; 3’d2: remout = 2 ; 3’d3: remout = 0 ; 3’d4: remout = 1 ; 3’d5: remout = 2 ; 3’d6: remout = 0 ; 3’d7: remout = 1 ; endcase

end endmodule

Figure 9.2: Verilog description of bit cell for Multiple-of-3 circuit.

//---// Multiple_of_3

// Determines if input is a multiple of 3 // Input:

// in - an 8-bit binary number // Output:

// out - true if in is a multiple of 3

//---module Multiple_of_3(in, out) ;

input [7:0] in ; output out ;

wire [15:0] rem ; // two bits of remainder per cell // instantiate 8 copies of the bit cell

Multiple_of_3_bit b7(in[7],2’b0,rem[15:14]) ; Multiple_of_3_bit b6(in[6],rem[15:14],rem[13:12]) ; Multiple_of_3_bit b5(in[5],rem[13:12],rem[11:10]) ; Multiple_of_3_bit b4(in[4],rem[11:10],rem[9:8]) ; Multiple_of_3_bit b3(in[3],rem[9:8],rem[7:6]) ; Multiple_of_3_bit b2(in[2],rem[7:6],rem[5:4]) ; Multiple_of_3_bit b1(in[1],rem[5:4],rem[3:2]) ; Multiple_of_3_bit b0(in[0],rem[3:2],rem[1:0]) ; // output is true if remainder out is zero wire out = (rem[1:0] == 2’b0) ;

endmodule

Figure 9.3: Verilog description of bit cell for Multiple-of-3 circuit.

module testMul3 ; reg [7:0] in ; reg error ; wire out ;

Multiple_of_3 dut(in, out) ; initial begin

in = 0 ; error = 0 ; repeat(256) begin

#100

// $display("%d %b",in,out) ; if(out != ((in %3) == 0)) begin

$display("ERROR %d -> %b",in,out) ; error = 1 ;

end

in = in + 1 ; end

if(error == 0) $display("PASS") ; end

endmodule

Figure 9.4: Verilog description of the test bench for the multiple-of-3 circuit.

module NextDayOfWeek(today, tomorrow) ; input [2:0] today ;

output [2:0] tomorrow ;

wire [2:0] tomorrow = (today == ‘SATURDAY) ? ‘SUNDAY : today + 3’d1 ; endmodule

Figure 9.5: Verilog description of the NextDayOfWeek module which increments the day of the week.

Figure 9.5 shows a Verilog module that increments the day of the week.

If the current day is ‘SATURDAY (which is defined to be 7) this module sets tomorrow’s day to be ‘SUNDAY (which is defined to be 1). If the current day is other than ‘SATURDAY the module just increments today to get tomorrow.

In Section 16.1 we will see that the NextDayOfWeek module is the combina-tional part of a counter, a circuit that increments its state. The variation here is that when the counter reaches ‘SATURDAY it resets back to ‘SUNDAY.

This module is coded using definitions for ‘SATURDAY and ‘SUNDAY. However it will only work if the days are represented by consecutive three-bit integers starting with ‘SUNDAY and ending with ‘SATURDAY. In Exercise 9–2 we explore writing a more general version of this module that will work with arbitrary representations for the days of the week.

Figure 9.6 shows a Verilog module that computes the number of days in a given month. This is just a simple case statement that uses a default case to handle the common case of a month with 31 days. This module would be a bit easier to read if we defined constants for the month names. However, we use numbers for months often enough in our daily lives that little is lost by using the numbers here.

The astute reader will have observed that this DaysInMonth module is not quite right. We haven’t considered leap years — when February has 29 days.

We leave it as an exercise for the reader (Exercise 9–3) to remedy this situation.

With our two submodules defined, we can now develop the full Tomorrow module. Figure 9.7 shows the code for our full tomorrow module. After the module, input/output, and signal declarations it starts by instantiating our two submodules. The NextDayOfWeek module directly generates the tomorrowDoW output. This is also the only code to use the todayDoW input. The day-of-week function is completely independent of the month and day-of-month function.

Next, the circuit instantiates the DaysInMonth submodule. This submodule generates an internal signal daysInMonth that encodes the last day of the cur-rent month. The tomorrow module then generates two other internal signals:

lastDayis true if today is the last day of the month and lastMonth is true if the current month is December. Using these two internal signals, the module then computes tomorrowMonth and tomorrowDoM using assign statements that use ? : statements.

module DaysInMonth(month, days) ;

input [3:0] month ; // month of the year 1 = Jan, 12 = Dec output [4:0] days ; // number of days in month

reg [4:0] days ; always @(month) begin

case(month)

4,6,9,11: days = 5’d30 ; // thirty days have September...

default: days = 5’d31 ; // all the rest have 31

2: days = 5’d28 ; // except for February which has 28 endcase

end endmodule

Figure 9.6: Verilog description of a module that computes the number of days in a month in a non-leap year.

Verifying the tomorrow circuit efficiently is a bit of a challenge. A brute force enumeration of all states requires simulating the circuit for 7 years worth of input dates — 2,555 inputs. We can reduce this to 365 inputs by observing that the day-of-week function is completely independent and can be verified independently. We can further collapse the set of tests by simulating only the beginning and end of each month.