Professional Documents
Culture Documents
An Integer Square Root Algorithm: Example 24
An Integer Square Root Algorithm: Example 24
71
Example 24
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
square = n^2
0
1
4
9
16
25
36
49
64
81
100
121
144
169
196
225
256
289
delta
3
5
7
9
11
13
15
17
19
21
23
25
27
29
31
33
delta/2-1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
72
Example 24
Our goal is to implement this algorithm in hardware using the same method that
we used in Example 23. The datapath for this square root algorithm is shown in Fig. 2.9.
We will limit the input value a[7:0] to eight bits so we can connect them to the eight
switches sw[7:0]. Thus, the register aReg will be an 8-bit register. From Table 2.1 the
maximum value of delta will be 33. This suggests that the size of the delta register
should be 6 bits. However, when we are done the final value of delta is divided by 2 and
then 1 is subtracted from this result. If the value is 33 but we only use a 5-bit register for
delta then the value in delta will be 1. When we divide this by 2 we will get 0, and when
we subtract 1 from 0 we get 11111, the lower four bits of which are equal to 15 the
correct result. Thus, we can get by with a 5-bit register for delta. However, from Table
2.1 the maximum value of square in the algorithm will be 256, and therefore the square
register must be 9 bits wide. The maximum square root value will be 15 and thus the
output will be stored in a 4-bit register.
In addition to the four registers aReg, sqReg, delReg, and outReg, this datapath
contains four combinational modules. The output, lteflg, of the <= module will be 1 if
square (the output of sqReg) is less than or equal to a (the output of aReg).
sw[7:0]
s[8:0]
ald
clr
aReg
clk
sqld
sqReg
sq[8:0]
square[7:0]
a[7:0]
9
reset
clk
dld
delReg
del[4:1]
clk
plus2
minus1
outin[3:0]
lteflg
reset
5 del[4:0]
adder8
<=
del2[4:0]
square[7:0]
outld
outReg
clr
clk
4
root[3:0]
The Verilog program in Listing 2.5 implements the complete datapath shown in
Fig. 2.9. The four registers have different bus widths and are initialized to different
values. The generic register described in the Verilog file regr2.v shown in Listing 2.6 is
used to instantiate all four registers in Listing 2.5. The two parameters BIT0 and BIT1 are
used to set the lower two bits of the generic register on reset. Note in Listing 2.5 that the
value of sqReg is initialized to 1 and the value of delReg is initialized to 3. In Listing 2.5
the combinational modules adder8, plus2, and minus1 are implemented with assign
statements, and the module lte is implemented by a separate always block.
The output signal lteflg in Fig. 2.9 is sent to the control unit. The control unit will
then provide the datapath with the load signals for all of the registers. The design of the
control unit will be described next.
// adder8
// plus2
// minus1
73
74
Example 24
75
clk
clr
clk
lteflg
sw[7:0]
go
ald
Datapath
Control Unit
root[3:0]
sqld
dld
outld
~go
start
go
test
~lteflg
square += delta
delta += 2
lteflg
done
update
delta/2 - 1
76
Example 24
Note that we have implemented the state machine in Listing 2.7 as a Moore
machine of the type shown in Fig. 1.37 with three always blocks: the sequential state
register block and the two combinational blocks C1 and C2. Note how the C1 block
finds the next state by directly implementing the state diagram in Fig. 2.11 with a case
statement. The output block C2 also uses a case statement to set the register load signals
to the proper values for each state. Verify that these load signals are appropriate for
implementing the square root algorithm.
Listing 2.7 SQRTctrl.v
// Example 24c: Square root control
module SQRTctrl (
input wire clk ,
input wire clr ,
input wire lteflg ,
input wire go ,
output reg ald ,
output reg sqld ,
output reg dld ,
output reg outld
);
reg[1:0] present_state, next_state;
parameter start = 2'b00, test =2'b01, update = 2'b10,
done = 2'b11; // states
// State registers
always @(posedge clk or posedge clr)
begin
if (clr == 1)
present_state <= start;
else
present_state <= next_state;
end
// C1 module
always @(*)
begin
case(present_state)
start: if(go == 1)
next_state = test;
else
next_state = start;
test: if(lteflg == 1)
next_state = update;
else
next_state = done;
update: next_state = test;
done: next_state = done;
default next_state = start;
endcase
end
77
The top-level design shown in Fig. 2.10 can be implemented in Verilog by simply
instantiating the datapath and control unit as shown in Listing 2.8. Note that we have
included an output signal done that goes high when the done state is entered. A
simulation of this program that computes the square root of 64 is shown in Fig. 2.12.
78
Example 24
To test the square root algorithm on the Nexys-2 board we will use the top-level
design shown in Fig. 2.13. When btn[3] is pressed to reset the circuit the decimal value
of the eight switch settings is displayed on the 7-segment display. We use the 8-bit
binary-to-BCD program in Listing 1.14 of Example 12 to do this conversion. When
btn[0] is pressed the sqrt component computes the square root of the switch settings, and
when the calculation is complete the done signal switches the multiplexer so that the
decimal value of the square root is displayed on the 7-segment display. Try it.
mclk 50 MHz
clkdiv
btn[0] btn[3]
clr
btn[3]
clk25
clk190
go
sw[7:0]
clr
clk
sqrt
root[3:0]
btn[3]
done
r[7:0]
1
mux2g
b[7:0]
binbcd8
0 & p[9:0]
cclk
x[15:0]
clr
x7segb
ld[7:0]
clr = btn[3];
r = {4'b0000,root};
x = {6'b000000,p};
ld = sw;
clkdiv U1 (.mclk(mclk),
.clr(clr),
.clk190(clk190),
.clk25(clk25)
);
sqrt U2 (.clk(clk25),
.clr(clr),
.go(btn[0]),
.sw(sw),
.done(done),
.root(root)
);
a_to_g[6:0]
an[3:0]
79
80
Example 24