Least Common Multiple (LCM)

advertisement
Least Common Multiple (LCM)
Task:
Implement an LCM algorithm that is able to handle any combination of 8-bit (sign bit
included) numbers. Use two's complement format to represent negative values. Provide the
circuit with an interface for repetitive data input (using buttons and switches) and result
output (using LEDs). The design should be developed in accordance with the same
methodology as described in the example below:
• prepare the flowchart of the algorithm that is based on the selected LCM
computation method
• prepare GSA and state transition table for the control part of the design
• develop a suitable datapath
Verify and implement the design on FPGA development board.
Greatest Common Divisor Example
The greatest common divisor of two non-zero integers is the largest positive integer that
divides both numbers without remainder. One way to compute GCD is to use Euclidean
algorithm. The flowchart of Euclidean algorithm is presented on Figure 1. For this example
it is assumed that input operands are unsigned 8-bit numbers and none of them is zero.
GCD circuit includes a control unit (FSM), which is complemented with a datapath. On this
stage the datapath consists of two registers (RG1 and RG2), multiplexers for selecting the
source of data to be stored in these registers and comparator logic. The remainder
computation is treated as “black box”.
As most of the basic FPGAs do not feature any dedicated logic for performing division, it
must be synthesized separately. A simple division algorithm is presented on Figure 2. At
each step it checks whether divisor, which is multiplied by corresponding power of two
(starting from the maximum possible), fits into dividend. If it doesn’t, then the dividend is
restored.
BEGIN
No
START
Yes
RG1 := OP1;
RG2 := OP2;
Yes
RG1 = RG2
No
RG1 < RG2
Yes
RG1 := RG2;
RG2 := RG1;
No
Remainder
Computation
Yes
Remainder = 0
No
READY := 1;
ANSW := RG2;
END
Figure 1: GCD Algorithm
Register RG1 is loaded with dividend, while register RG2 – with divisor. At first the divisor
is normalized. As the quotient is of no interest, its computation is omitted from the
algorithm. After the final run, RG1 should contain the remainder, while divisor in RG2 is
back to normal. Note, that RG1 is a 9-bit registers, as it should include a sign bit as well.
Remainder computation algorithm invokes additional elements in the datapath: Arithmetic
Logic Unit (ALU) and up/down counter. ALU is, in a sense, a custom block, its
functionality is design specific. For this particular algorithm ALU should handle addition,
subtraction and right/left shift operations, as well as comparison. The block scheme of the
complete datapath is presented on Figure 3.
Remainder
Computation
RG2(7) = 1
No
Yes
L1(RG2.0);
C := C + 1;
YesNo
RG1 := RG1 - RG2;
Yes
RG1(8) = 1
No
RG1 := RG1 + RG2;
Yes
C=0
No
R1(0.RG2);
C := C - 1;
Figure 2: Remainder Computation Algorithm
Elements of the datapath are controlled via eleven (Y10-Y0) signals – a control word. Y0,
Y1 and Y2 are enable signals for the registers (RG1 and RG2) and the counter. Y3 signal
selects the counting direction. Y7-Y4 control the multiplexers, which feed data to registers
RG1 and RG2. Y8 and Y9 select the ALU operation (addition, subtraction or right/left
shift). Y10 enables the ANSW output, when the result is ready.
The control unit gets feedback from datapath via six (X6-X1) signals. X1 indicates whether
the content of RG1 equals the content of RG2. X2 signals whether the value stored in RG1
is greater than the value of RG2. X3 is the most significant bit of RG2. X4 is the sign bit of
RG1. Signals X5 and X6 indicate when content of counter and RG1 equal zero.
y5 y4
y0 x4 x6
y9 y8
OP1
RG1
x1
ALU
x2
RG2
OP2
y1
y7 y6
x3
ANSW
Counter
y3
y2
x5
y10
DATA PATH
UNIT
Figure 3: Datapath Of GCD Circuit
At this stage it is possible to represent the control unit by means of graph-scheme of
algorithm (GSA). In this GSA the computational statements (actions of ALU and counter)
are replaced with the corresponding control signals (Y-s) and the conditions - with binary
conditions signals (X-s). Simultaneously executed statements are grouped into common
blocks. The resultant GSA is presented on Figure 4. It can be synthesized as either Moore
or Mealy FSM to form a control unit for the GCD circuit.
BEGIN
0
x0
1
y7 y5 y1 y0
1
0
x1
x2
1
y6 y4 y1 y0
0
x3
0
y9 y2 y1
1
y8 y0
1
x4
0
y0
1
1
x6
x5
0
y9 y8 y3 y2 y1
0
y10
END
Figure 4: GSA Of GCD Algoritm
VHDL descriptions of the main components of the datapath are provided in Listing 1,
Listing 2 and Listing 3. Signals reg and counter_value infer registers during synthesis, as
they are assigned a value inside an edge sensitive if statement. This makes the else path
excessive, as the storage element should hold the data unchanged in any other case. Both
registers are write-protected with enable signals, so they could store data only when it is
required. Counter's activity is also protected with enable signal.
Note, that example register and example counter are fully synchronous. Their control
signals are not present in the sensitivity list, because such circuits should react to the rising
edge of the clock signal only.
Listing 1: VHDL Description of ALU
process (OP1, OP2, op_sel)
begin
case op_sel is
when "00" => result <= OP1 + OP2;
when "01" => result <= OP1 - OP2;
when "10" => result <= OP2(7 downto 0)&'0';
when "11" => result <= '0'&OP2(8 downto 1);
when others => result <= (others => '0');
end case;
if OP1 = OP2 then
equal <= '1';
else
equal <= '0';
end if;
if OP1 < OP2 then
greater <= '1';
else
greater <= '0';
end if;
end process;
The counter should definitely be implemented as a signal (not a variable), because its value
must be available to other processes. ALU is a purely combinational circuit, thus it reacts to
the change on any of its inputs.
Listing 2: VHDL Description of Register
process (clk)
begin
if clk'event and clk = '1' then
if reg_en = '1' then
reg <= reg_input;
end if;
end if;
end process;
Listing 3: VHDL Description of Up/Down Counter
process (clk)
begin
if clk'event and clk = '1' then
if counter_en = '1' then
if count_direction = '1' then
counter_value <= counter_value - 1;
else
counter_value <= counter_value + 1;
end if;
end if;
end if;
end process;
To check zero equality of a register, its content can be NORed bitwise. The condition
becomes High only when all bits of the register are Low. VHDL description of a zero
equality check for a 4-bit register is presented in Listing 4.
Listing 4: Zero Equality Check for a 4-bit Register
reg_zero <= not (reg(3) or reg(2) or reg(1) or reg(0) );
Download