OpenCores
URL https://opencores.org/ocsvn/signed_unsigned_multiplier_and_divider/signed_unsigned_multiplier_and_divider/trunk

Subversion Repositories signed_unsigned_multiplier_and_divider

[/] [signed_unsigned_multiplier_and_divider/] [trunk/] [readme.txt] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 zpekic
Goal:
2
 
3
Implement signed/unsigned 32/16 bit multiplier/divider using a finite state machine (and use it for a fun project)
4
 
5
Background:
6
 
7
I needed a signed / unsigned multiplier / divider for a different project, and decided to use algorithms described in this book: https://www.amazon.com/Computer-Organization-Architecture-Principles-Structure/dp/0024154954
8
 
9
The interface is self-explanatory and should be easy enough to use in various projects:
10
 
11
 
12
entity signedmultiplier is
13
    Port ( reset : in  STD_LOGIC;               -- Active high to initialize. Note that ready will be low as long as reset remains high
14
           clk : in  STD_LOGIC;                 -- Clock to drive the FSM
15
           start : in  STD_LOGIC;               -- Apply high for at least 1 clock cycle to start computation
16
           mode: in STD_LOGIC_VECTOR(1 downto 0);-- 00: unsigned multiply, 01: signed multiply, 10: unsigned divide, 11: signed divide
17
           dividend32: in STD_LOGIC;            -- 0: 16/16 divide, 1: 32/16 divide. ignored for multiplication
18
           arg0h : in  STD_LOGIC_VECTOR (15 downto 0);          -- used as MSW for 32/16 divide
19
           arg0l : in  STD_LOGIC_VECTOR (15 downto 0);          -- LSW for 32/16 divide, factor0 for 16*16 multiplication
20
           arg1 : in  STD_LOGIC_VECTOR (15 downto 0);           -- factor1 for 16*16 multiplication
21
           result : buffer  STD_LOGIC_VECTOR (31 downto 0);     -- 32 bit result when multiplying, when dividing quotient is MSW, remainder is LSW
22
           ready : out  STD_LOGIC;              -- goes high when done
23
           error : out  STD_LOGIC;              -- goes high when dividing by 0
24
           zero : out  STD_LOGIC;               -- quotient is zero (divide) or whole product is zero (multiplication)
25
           sign : out  STD_LOGIC;               -- same result checked like for zero, only meaningful for signed operation
26
           debug : out STD_LOGIC_VECTOR(3 downto 0));   -- debug output (leave open)
27
end signedmultiplier;
28
 
29
The 16-bit multiply / divide modes have been tested pretty thoroughly, but the 32/16 may still have some bugs...
30
 
31
 
32
Debugging:
33
 
34
Very simple hardware debugging was used - a single step circuit combined with key signals from the guts of the components, displaying the data on Mercury baseboard 7seg LEDs and using buttons and switches there.
35
 
36
Testing:
37
 
38
To test the functionality of the multiplier / dividers, 3 different approaches can be used:
39
 
40
---------------------------------------------------------------------------------------------------
41
SW(4) SW(0)     Circuit                                                 Input           Output
42
---------------------------------------------------------------------------------------------------
43
 
44
 
45
1       0        Prime number generator                                  N/A             N/A
46
1       1       - " -                                                   UART            UART
47
---------------------------------------------------------------------------------------------------
48
 
49
The I/O can be thought of as 2 input (BTN(1) pressed) registers that are "shifted up" by 1 hex digit any time PMOD keyboard is pressed, or a character is received through UART. When BTN(1) is released, result MSW or LSW are displayed on the LEDs.
50
 
51
Prime number generator:
52
 
53
The algorithm used is described in "findprimes.bs2" Basic Stamp program. It uses unsigned multiplication and division (checking for remainder) to determine if the integer is prime or not. It runs on a "mini CPU" which is a simple data path processor driven by microcode which encodes the prime finding algorithm. When a prime number is found, its order and value are sent through UART (57600 baud, 8-N-1)
54
 
55
Here is one example of operation:
56
 
57
1. Switches: 01111XXX1 = no single step, 25MHz, prime generator, UART use
58
2. Press button 3 to start clock
59
3. Press buttons 1 to display lower boundary and enter as hex through serial terminal (e.g. 0000)
60
4. Press buttons 1 and 0 to display upper boundary and enter as hex through serial terminal (e.g. FFFF)
61
5. Press button 2 to start algorithm
62
6. Prime number index and value are displayed in the serial terminal (in decimal format)
63
7. When done, you can restart at step 2.
64
 
65
Main components of the prime generator CPU are:
66
 
67
> 3 16-bit registers n, m, i (this one is just to count the number of primes found)
68
> 2 8-input 16-bit multiplexers to feed the data to ALU inputs
69
> 16-bit ALU, with 2's complement addition and substraction, and special operations to convert BCD nibbles to ASCII
70
> 16-input condition code multiplexer
71
> Microcode store (32 words by 32 bits deep) encoding the prime number finding algorithm
72
> Control unit - contains a 4 deep 8-bit microinstruction pointer stack and can execute goto/gosub/wait/return etc. microinstructions
73
 
74
ALU output is connected to the 3 registers, and to UART (LSB) to output ASCII chars. In addition, there are 2 binary to BCD encoders, one for i, one for n registers:
75
 
76
entity bin2bcd is
77
    Port (      reset : in  STD_LOGIC;          -- Initialize when high, note that it will drive ready low
78
                clk : in  STD_LOGIC;            -- Drives the FSM
79
                start : in  STD_LOGIC;          -- Keep high for at least 1 clock cycle to start conversion
80
                bin : in  STD_LOGIC_VECTOR (15 downto 0);       -- 16-bit unsigned binary input value
81
                ready : out  STD_LOGIC;         -- pulse high when conversion is done
82
                bcd : buffer STD_LOGIC_VECTOR (23 downto 0);    -- 6 BCD digits output
83
                debug: out STD_LOGIC_VECTOR(3 downto 0));       -- debug port, leave open
84
end bin2bcd;
85
 
86
The binary to BCD converter is also implemented as FSM, and contains a table 2^0 to 2^15 in BCD format, a shift register and a 6 BCD digit adder that accumulates the result.
87
 
88
Hardware used:
89
 
90
* Micronova Mercury FPGA development board https://www.micro-nova.com/mercury/
91
* Mercury baseboard https://www.micro-nova.com/mercury-baseboard/
92
* Parallax USB2SER development board https://www.parallax.com/product/28024
93
* https://store.digilentinc.com/pmod-kypd-16-button-keypad/ (optional)
94
 
95
Development tools:
96
 
97
* Xilinx ISE 14.7 (nt) - free version
98
 
99
* Parallax Propeller IDE serial terminal
100
Probably most other generic serial terminal window programs can be used
101
 
102
Software and code (re)used:
103
 
104
* VHDL uart-for-fpga by Jakub Cabal (https://github.com/jakubcabal/uart-for-fpga)
105
 
106
Possible next steps:
107
 
108
- use in other projects
109
 
110
Known problems:
111
 
112
It would be exciting to see if somebody could use this core in their own projects. If so, shoot me an email to zpekic@hotmail.com.
113
 
114
Latest version of the source code (under appropriate license) is available at https://github.com/zpekic/
115
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.