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/] [sys_primegen.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 zpekic
----------------------------------------------------------------------------------
2
-- Company: @Home
3
-- Engineer: zpekic@hotmail.com
4
-- 
5
-- Create Date: 02/26/2018 11:13:02 PM
6
-- Design Name: Prime number finder
7
-- Module Name: sys_prime - Behavioral
8
-- Project Name: Wrapper around signed/unsigned multiply/divide
9
-- Target Devices: https://www.micro-nova.com/mercury/ + Baseboard
10
-- Input devices: 
11
--      https://store.digilentinc.com/pmod-kypd-16-button-keypad/ (use when SW(0) is off)
12
--      https://www.parallax.com/product/28024 (use when SW(0) is on, RX = PMOD(0), TX = PMOD(4), RST = N/C, GND = PMOD_GND)
13
-- Tool Versions: ISE 14.7 (nt)
14
-- Description: 
15
-- 
16
-- Dependencies: 
17
-- 
18
-- Revision:
19
-- Revision 0.99 - Kinda works...
20
-- Additional Comments:
21
----------------------------------------------------------------------------------
22
 
23
 
24
library IEEE;
25
use IEEE.STD_LOGIC_1164.ALL;
26
 
27
-- Uncomment the following library declaration if using
28
-- arithmetic functions with Signed or Unsigned values
29
use IEEE.NUMERIC_STD.ALL;
30
 
31
-- Uncomment the following library declaration if instantiating
32
-- any Xilinx leaf cells in this code.
33
--library UNISIM;
34
--use UNISIM.VComponents.all;
35
 
36
use work.sys_primegen_package.all;
37
entity sys_primegen is
38
    Port (
39
                                -- 50MHz on the Mercury board
40
                                CLK: in std_logic;
41
                                -- Master reset button on Mercury board
42
                                USR_BTN: in std_logic;
43
                                -- Switches on baseboard
44
                                -- SW(0) -- 0 enter Arg0 and Arg1 using PMOD keyboard, 1 enter using serial (UART)
45
                                -- SW(1) -- 0 (16/16 or 16*16), 1 (32/16 - divide only)   
46
                                -- SW(2) -- 0 (unsigned), 1 (signed)
47
                                -- SW(3) -- 0 (multiply), 1 (divide)
48
                                -- SW(4) -- 0 manual mode (see SW3, 2, 1), 1 find prime numbers using microcoded program
49
                                -- SW(6 downto 5) -- system clock speed 
50
                                --   0   0      1Hz     (can be used with SS mode)
51
                                --   0   1      1024Hz (can be used with SS mode)
52
                                --   1   0  6.125MHz
53
                                --   1   1  25MHz
54
                                -- SW(7)
55
                                --   0   single step mode off (BTN3 should be pressed once to start the system)
56
                                --   1   single step mode on (use with BTN3)
57
                                SW: in std_logic_vector(7 downto 0);
58
                                -- Push buttons on baseboard
59
                                -- BTN0 - LED display select 0
60
                                -- BTN1 - LED display select 1
61
                                -- BTN2 - start the multiply or divide operation, or find prime algorithm
62
                                -- BTN3 - single step clock cycle forward if in SS mode (NOTE: single press on this button is needed after reset to unlock SS circuit)
63
                                BTN: in std_logic_vector(3 downto 0);
64
                                -- Stereo audio output on baseboard
65
                                --AUDIO_OUT_L, AUDIO_OUT_R: out std_logic;
66
                                -- 7seg LED on baseboard 
67
                                A_TO_G: out std_logic_vector(6 downto 0);
68
                                AN: out std_logic_vector(3 downto 0);
69
                                DOT: out std_logic;
70
                                -- 4 LEDs on Mercury board
71
                                LED: out std_logic_vector(3 downto 0);
72
                                -- ADC interface
73
                                -- channel      input
74
                                -- 0                    Audio Left
75
                                -- 1                    Audio Right
76
                                -- 2                    Temperature
77
                                -- 3                    Light   
78
                                -- 4                    Pot
79
                                -- 5                    Channel 5 (free)
80
                                -- 6                    Channel 6 (free)
81
                                -- 7                    Channel 7 (free)
82
                                --ADC_MISO: in std_logic;
83
                                --ADC_MOSI: out std_logic;
84
                                --ADC_SCK: out std_logic;
85
                                --ADC_CSN: out std_logic;
86
                                --PMOD interface
87
                                PMOD: inout std_logic_vector(7 downto 0)
88
 
89
          );
90
end sys_primegen;
91
 
92
architecture Structural of sys_primegen is
93
 
94
component clock_divider is
95
    Port ( reset : in  STD_LOGIC;
96
           clock : in  STD_LOGIC;
97
           slow : out  STD_LOGIC_VECTOR (11 downto 0);
98
                          baud : out STD_LOGIC_VECTOR(7 downto 0);
99
           fast : out  STD_LOGIC_VECTOR (4 downto 0)
100
                         );
101
end component;
102
 
103
component clocksinglestepper is
104
    Port ( reset : in STD_LOGIC;
105
           clock0_in : in STD_LOGIC;
106
           clock1_in : in STD_LOGIC;
107
           clock2_in : in STD_LOGIC;
108
           clock3_in : in STD_LOGIC;
109
           clocksel : in STD_LOGIC_VECTOR(1 downto 0);
110
           modesel : in STD_LOGIC;
111
           singlestep : in STD_LOGIC;
112
           clock_out : out STD_LOGIC);
113
end component;
114
 
115
component debouncer8channel is
116
    Port ( clock : in  STD_LOGIC;
117
           reset : in  STD_LOGIC;
118
           signal_raw : in  STD_LOGIC_VECTOR(7 downto 0);
119
           signal_debounced : out  STD_LOGIC_VECTOR(7 downto 0));
120
end component;
121
 
122
component fourdigitsevensegled is
123
    Port ( -- inputs
124
                          data : in  STD_LOGIC_VECTOR (15 downto 0);
125
           digsel : in  STD_LOGIC_VECTOR (1 downto 0);
126
           showdigit : in  STD_LOGIC_VECTOR (3 downto 0);
127
           showdot : in  STD_LOGIC_VECTOR (3 downto 0);
128
           showsegments : in  STD_LOGIC;
129
                          -- outputs
130
           anode : out  STD_LOGIC_VECTOR (3 downto 0);
131
           segment : out  STD_LOGIC_VECTOR (7 downto 0)
132
                         );
133
end component;
134
 
135
component signedmultiplier is
136
    Port ( reset : in  STD_LOGIC;
137
           clk : in  STD_LOGIC;
138
           start : in  STD_LOGIC;
139
                          mode: in STD_LOGIC_VECTOR(1 downto 0);
140
                          dividend32: in STD_LOGIC;
141
           arg0h : in  STD_LOGIC_VECTOR (15 downto 0);
142
           arg0l : in  STD_LOGIC_VECTOR (15 downto 0);
143
           arg1 : in  STD_LOGIC_VECTOR (15 downto 0);
144
           result : out  STD_LOGIC_VECTOR (31 downto 0);
145
           ready : out  STD_LOGIC;
146
           error : out  STD_LOGIC;
147
           zero : out  STD_LOGIC;
148
           sign : out  STD_LOGIC;
149
                          debug : out STD_LOGIC_VECTOR(3 downto 0)
150
                          );
151
end component;
152
 
153
component bin2bcd is
154
    Port ( reset : in  STD_LOGIC;
155
           clk : in  STD_LOGIC;
156
           start : in  STD_LOGIC;
157
           bin : in  STD_LOGIC_VECTOR (15 downto 0);
158
                          ready : out  STD_LOGIC;
159
           bcd : out  STD_LOGIC_VECTOR (23 downto 0);
160
                          debug: out STD_LOGIC_VECTOR(3 downto 0));
161
end component;
162
 
163
component PmodKYPD is
164
    Port (
165
           clk : in  STD_LOGIC;
166
                          reset: in STD_LOGIC;
167
                          bcdmode: in STD_LOGIC;
168
           Col : out  STD_LOGIC_VECTOR (3 downto 0);
169
                          Row : in  STD_LOGIC_VECTOR (3 downto 0);
170
                          key_code: out  STD_LOGIC_VECTOR (3 downto 0);
171
                          key_down: out STD_LOGIC
172
         );
173
end component;
174
 
175
component UART is
176
    Generic (
177
        CLK_FREQ      : integer := 50e6;   -- system clock frequency in Hz
178
        BAUD_RATE     : integer := 115200; -- baud rate value
179
        PARITY_BIT    : string  := "none"; -- type of parity: "none", "even", "odd", "mark", "space"
180
        USE_DEBOUNCER : boolean := True    -- enable/disable debouncer
181
    );
182
    Port (
183
        CLK         : in  std_logic; -- system clock
184
        RST         : in  std_logic; -- high active synchronous reset
185
        -- UART INTERFACE
186
        UART_TXD    : out std_logic; -- serial transmit data
187
        UART_RXD    : in  std_logic; -- serial receive data
188
        -- USER DATA INPUT INTERFACE
189
        DATA_IN     : in  std_logic_vector(7 downto 0); -- input data
190
        DATA_SEND   : in  std_logic; -- when DATA_SEND = 1, input data are valid and will be transmit
191
        BUSY        : out std_logic; -- when BUSY = 1, transmitter is busy and you must not set DATA_SEND to 1
192
        -- USER DATA OUTPUT INTERFACE
193
        DATA_OUT    : out std_logic_vector(7 downto 0); -- output data
194
        DATA_VLD    : out std_logic; -- when DATA_VLD = 1, output data are valid
195
        FRAME_ERROR : out std_logic  -- when FRAME_ERROR = 1, stop bit was invalid
196
    );
197
end component;
198
 
199
component rom32x32 is
200
    Port ( nCS : in STD_LOGIC;
201
           a : in STD_LOGIC_VECTOR (4 downto 0);
202
           d : out STD_LOGIC_VECTOR (31 downto 0));
203
end component;
204
 
205
component sequencer is
206
    Port ( reset : in  STD_LOGIC;
207
           clk : in  STD_LOGIC;
208
           operation : in  STD_LOGIC_VECTOR (2 downto 0);
209
           condition : in  STD_LOGIC;
210
           directvalue : in  STD_LOGIC_VECTOR (7 downto 0);
211
           uIP : out  STD_LOGIC_VECTOR (7 downto 0));
212
end component;
213
 
214
component alu_with_hex2ascii is
215
    Port ( a : in  STD_LOGIC_VECTOR (15 downto 0);
216
           b : in  STD_LOGIC_VECTOR (15 downto 0);
217
                          bcdmode: in STD_LOGIC;
218
           operation : in  STD_LOGIC_VECTOR (2 downto 0);
219
           carry_in : in  STD_LOGIC;
220
           carry_out : out  STD_LOGIC;
221
           zero : out  STD_LOGIC;
222
           y : out  STD_LOGIC_VECTOR (15 downto 0));
223
end component;
224
 
225
 
226
signal Reset: std_logic;
227
signal clock_main: std_logic;
228
signal switch: std_logic_vector(7 downto 0);
229
signal button: std_logic_vector(3 downto 0);
230
signal led_bus: std_logic_vector(19 downto 0);
231
signal display0, display1: std_logic_vector(15 downto 0);
232
signal flash: std_logic;
233
signal freq2k, freq1k, freq512, freq256, freq128, freq64, freq32, freq16, freq8, freq4, freq2, freq1: std_logic;
234
signal freq38400, freq19200, freq9600, freq4800, freq2400, freq1200, freq600, freq300: std_logic;
235
signal freq25M, freq12M5, freq6M25, freq3M125, freq1M5625: std_logic;
236
 
237
signal arg0, arg1: std_logic_vector(31 downto 0);
238
signal key_pulse, rxd_pulse: std_logic;
239
signal key_code: std_logic_vector(3 downto 0);
240
signal result: std_logic_vector(31 downto 0);
241
alias prod_h: std_logic_vector(15 downto 0) is result(31 downto 16);
242
alias prod_l: std_logic_vector(15 downto 0) is result(15 downto 0);
243
alias quotient: std_logic_vector(15 downto 0) is result(31 downto 16);
244
alias remainder: std_logic_vector(15 downto 0) is result(15 downto 0);
245
 
246
signal sm_ready, sm_error, sm_zero, sm_sign: std_logic;
247
signal sm_control: std_logic_vector(3 downto 0);
248
signal sm_input1, sm_input0l, sm_input0h: std_logic_vector(15 downto 0);
249
 
250
--signal txd_data: std_logic_vector(7 downto 0);
251
signal txd_busy, txd: std_logic;
252
signal rxd_data: std_logic_vector(7 downto 0);
253
signal rxd_valid, rxd_valid_delayed, rxd_error, uart_send: std_logic;
254
signal rxd_pulsecnt: integer range 0 to 15;
255
signal kbd_col: std_logic_vector(3 downto 0);
256
signal rxd_code: std_logic_vector(4 downto 0);
257
signal input_pulse: std_logic;
258
signal input_code: std_logic_vector(3 downto 0);
259
signal send_previous, send_current: std_logic_vector(7 downto 0);
260
 
261
-- specialized "CPU" ---
262
signal condition: std_logic;
263
signal uIP: std_logic_vector(7 downto 0);
264
signal alu_c, alu_z: std_logic;
265
signal n, m, i: std_logic_vector(15 downto 0);
266
signal alu_y, alu_a, alu_b: std_logic_vector(15 downto 0);
267
signal i_bcd, n_bcd: std_logic_vector(23 downto 0);
268
signal i_bcdready, n_bcdready: std_logic;
269
 
270
signal uInstruction: std_logic_vector(31 downto 0);
271
alias u_value: std_logic_vector(7 downto 0) is uInstruction(31 downto 24);
272
alias u_muxa: std_logic_vector(2 downto 0) is uInstruction(23 downto 21);
273
alias u_muxb: std_logic_vector(2 downto 0) is uInstruction(20 downto 18);
274
alias u_alu:  std_logic_vector(2 downto 0) is uInstruction(17 downto 15);
275
alias u_ci: std_logic is uInstruction(14);
276
alias u_i: std_logic is uInstruction(13);
277
alias u_m: std_logic is uInstruction(12);
278
alias u_n: std_logic is uInstruction(11);
279
alias u_mode: std_logic_vector(1 downto 0) is uInstruction(10 downto 9);
280
alias u_multdiv: std_logic is uInstruction(8);
281
alias u_uart: std_logic is uInstruction(7);
282
alias u_opsequence: std_logic_vector(2 downto 0) is uInstruction(6 downto 4);
283
alias u_condselect: std_logic_vector(3 downto 0) is uInstruction(3 downto 0);
284
-- HACKHACK "faked" ucode control signals
285
signal u_i2bcdstart: std_logic;
286
signal u_n2bcdstart: std_logic;
287
 
288
begin
289
 
290
         Reset <= USR_BTN;
291
 
292
        -- DISPLAY
293
        flash <= (not sm_error) or freq2; -- blink in hold bus mode!
294
 
295
        display0 <= result(15 downto 0) when switch(4) = '0' else uIP & uInstruction(7 downto 0);
296
        display1 <= result(31 downto 16) when switch(4) = '0' else alu_y;
297
 
298
        with button(1 downto 0) select
299
                led_bus(15 downto 0) <= display0 when "00",
300
                                                                                display1 when "01",
301
                                                                                arg0(15 downto 0) when "10",
302
                                                                                arg1(15 downto 0) when others;
303
 
304
         LED(3 downto 2) <= sm_sign & sm_zero when switch(4) = '0' else alu_c & condition;
305
         LED(1) <= sm_ready;
306
         LED(0) <= clock_main;
307
    led4x7: fourdigitsevensegled port map (
308
                          -- inputs
309
                          data => led_bus(15 downto 0),
310
           digsel(1) => freq1k,
311
                          digsel(0) => freq2k,
312
           showdigit(3) => flash,
313
           showdigit(2) => flash,
314
           showdigit(1) => flash,
315
           showdigit(0) => flash,
316
           showdot => led_bus(19 downto 16),
317
           showsegments => '1',
318
                          -- outputs
319
           anode => AN,
320
           segment(6 downto 0) => A_TO_G(6 downto 0),
321
                          segment(7) => DOT
322
                         );
323
 
324
    -- FREQUENCY GENERATOR
325
    one_sec: clock_divider port map
326
    (
327
        clock => CLK,
328
        reset => Reset,
329
        slow(11) => freq1, -- 1Hz
330
        slow(10) => freq2, -- 2Hz
331
        slow(9) => freq4, -- 4Hz
332
        slow(8) => freq8, -- 8Hz
333
        slow(7) => freq16,  -- 16Hz
334
        slow(6) => freq32,  -- 32Hz
335
        slow(5) => freq64,  -- 64Hz
336
        slow(4) => freq128,  -- 128Hz
337
        slow(3) => freq256,  -- 256Hz
338
        slow(2) => freq512,  -- 512Hz
339
        slow(1) => freq1k,  -- 1024Hz
340
        slow(0) => freq2k,  -- 2048Hz
341
                  baud(7) => freq300,
342
                  baud(6) => freq600,
343
                  baud(5) => freq1200,
344
                  baud(4) => freq2400,
345
                  baud(3) => freq4800,
346
                  baud(2) => freq9600,
347
                  baud(1) => freq19200,
348
                  baud(0) => freq38400,
349
                  fast(4) => freq1M5625,
350
                  fast(3) => freq3M125,
351
                  fast(2) => freq6M25,
352
                  fast(1) => freq12M5,
353
                  fast(0) => freq25M
354
    );
355
 
356
        -- DEBOUNCE the 8 switches and 4 buttons
357
    debouncer_sw: debouncer8channel port map (
358
        clock => freq256,
359
        reset => Reset,
360
        signal_raw => SW,
361
        signal_debounced => switch
362
    );
363
 
364
    debouncer_btn: debouncer8channel port map (
365
        clock => freq256,
366
        reset => Reset,
367
        signal_raw(7 downto 4) => "1111", --PMOD(3 downto 0),
368
        signal_raw(3 downto 0) => BTN(3 downto 0),
369
                  signal_debounced(7 downto 4) => open,
370
        signal_debounced(3 downto 0) => button
371
    );
372
 
373
        -- Single step by each clock cycle, slow or fast
374
        ss: clocksinglestepper port map (
375
        reset => Reset,
376
        clock0_in => freq2,
377
        clock1_in => freq2k,
378
        clock2_in => freq6M25,
379
        clock3_in => freq12M5,
380
        clocksel => switch(6 downto 5),
381
        modesel => switch(7),
382
        singlestep => button(3),
383
        clock_out => clock_main
384
    );
385
 
386
        -- UART for serial input / output
387
        sio: UART
388
         generic map
389
         (
390
                --CLK_FREQ => 100e6,
391
                BAUD_RATE => 57600
392
                --PARITY_BIT => "even"
393
                --USE_DEBOUNCER => false
394
         )
395
         port map
396
         (
397
        CLK => CLK,
398
        RST => Reset,
399
        -- UART INTERFACE
400
        UART_TXD => txd, -- serial transmit data
401
        UART_RXD => PMOD(4), -- serial receive data
402
        -- USER DATA INPUT INTERFACE
403
        DATA_IN  => alu_y(7 downto 0),
404
        DATA_SEND => uart_send,
405
        BUSY  => txd_busy,
406
        -- USER DATA OUTPUT INTERFACE
407
        DATA_OUT => rxd_data,
408
        DATA_VLD => rxd_valid,
409
        FRAME_ERROR => rxd_error
410
    );
411
 
412
        -- KEYBOARD
413
        kbd: PmodKYPD Port map
414
                        ( clk => freq1k,
415
                          reset => reset,
416
                          bcdmode => '0',
417
           Col(3) => kbd_col(3), --PMOD(0), -- out
418
           Col(2) => kbd_col(2), --PMOD(1),
419
           Col(1) => kbd_col(1), --PMOD(2),
420
           Col(0) => kbd_col(0), --PMOD(3),
421
                          Row(3) => PMOD(4), -- in
422
                          Row(2) => PMOD(5),
423
                          Row(1) => PMOD(6),
424
                          Row(0) => PMOD(7),
425
                          key_code => key_code,
426
                          key_down => key_pulse
427
                        );
428
 
429
-- output to PMOD is either keyboard columns or UART TXD        
430
PMOD(3 downto 0) <= kbd_col(0) & kbd_col(1) & kbd_col(2) & kbd_col(3) when switch(0) = '0' else "111" & txd;
431
input_pulse <= key_pulse when switch(0) = '0' else rxd_pulse;
432
input_code <= key_code when switch(0) = '0' else rxd_code(3 downto 0);
433
 
434
-- convert from 8-bit ASCII to hex
435
gethexcode: process(rxd_data, rxd_valid, rxd_error)
436
begin
437
        if (rising_edge(rxd_valid)) then
438
                if (rxd_error = '1') then
439
                        rxd_code <= "01111";
440
                else
441
                        case rxd_data is
442
                                when X"30" => rxd_code <= "10000"; -- 0
443
                                when X"31" => rxd_code <= "10001";
444
                                when X"32" => rxd_code <= "10010";
445
                                when X"33" => rxd_code <= "10011";
446
                                when X"34" => rxd_code <= "10100";
447
                                when X"35" => rxd_code <= "10101";
448
                                when X"36" => rxd_code <= "10110";
449
                                when X"37" => rxd_code <= "10111";
450
                                when X"38" => rxd_code <= "11000";
451
                                when X"39" => rxd_code <= "11001"; -- 9
452
                                when X"41" => rxd_code <= "11010"; -- A
453
                                when X"42" => rxd_code <= "11011"; -- B
454
                                when X"43" => rxd_code <= "11100"; -- C
455
                                when X"44" => rxd_code <= "11101"; -- D
456
                                when X"45" => rxd_code <= "11110"; -- E
457
                                when X"46" => rxd_code <= "11011"; -- F
458
                                when X"61" => rxd_code <= "11010"; -- a
459
                                when X"62" => rxd_code <= "11011"; -- b
460
                                when X"63" => rxd_code <= "11100"; -- c
461
                                when X"64" => rxd_code <= "11101"; -- d
462
                                when X"65" => rxd_code <= "11110"; -- e
463
                                when X"66" => rxd_code <= "11111"; -- f
464
                                when others  => rxd_code <= "01111";
465
                        end case;
466
                end if;
467
        end if;
468
end process;
469
 
470
-- delay rxd_valid to avoid capturing wrong data when generating pulse
471
delayrxdvalue: process(clk, rxd_valid)
472
begin
473
        if (rising_edge(clk)) then
474
                rxd_valid_delayed <= rxd_valid;
475
        end if;
476
end process;
477
 
478
rxd_pulse <= rxd_code(4) when rxd_valid_delayed = '1' else '0';
479
 
480
-- store incoming hex chars in either input registers    
481
keyin: process(input_pulse, input_code)
482
begin
483
        if (rising_edge(input_pulse)) then
484
                if (button(1) = '1') then
485
                        if (button(0) = '0') then
486
                                arg0 <= arg0(27 downto 0) & input_code;
487
                        else
488
                                arg1 <= arg1(27 downto 0) & input_code;
489
                        end if;
490
                end if;
491
        end if;
492
end process;
493
 
494
-- Mini CPU to execute find prime numbers microcode
495
 
496
-- This weird logic is added to save on uInstruction count as it allows to trigger "send" signal for UART in one clock cycle
497
-- and wait for the readyness in the same cycle. Otherwise 2 would be required. Note that the clock is high frequency for this to work.
498
triggersend: process(reset, freq25M, u_uart, uIP)
499
begin
500
        if (reset = '1') then
501
                send_previous <= X"FF";
502
                send_current <= X"FF";
503
        else
504
                if (rising_edge(freq25M) and u_uart = '1') then
505
                        send_previous <= send_current;
506
                        send_current <= uIP;
507
                end if;
508
        end if;
509
end process;
510
 
511
uart_send <= '0' when send_previous = send_current else '1';
512
 
513
-- condition codes used by the sequencer
514
with u_condselect select
515
        condition <=    button(2)                               when cond_buttonstart,
516
                                                txd_busy                                when cond_uartbusy,
517
                                                alu_c and not alu_z     when cond_alugreaterthan,
518
                                                not alu_c                               when cond_alulessthan,
519
                                                sm_ready                                        when cond_muldivready,
520
                                                alu_z                                           when cond_aluzero,
521
                                                sm_error                                        when cond_muldiverror,
522
                                                '0'                                              when cond_false,
523
                                                not txd_busy                    when cond_uartready,
524
                                                i_bcdready                              when cond_ibcdready,
525
                                                n_bcdready                              when cond_nbcdready,
526
                                                alu_c                                   when cond_alugreaterorequal,
527
                                                not sm_ready                    when cond_muldivnotready,
528
                                                not alu_z                               when cond_alunotzero,
529
                                                not sm_error                    when cond_muldivok,
530
                                                '1'                                             when others;
531
 
532
-- contains the prime number finding algorithm. See "findprimes.bs2" Basic Stamp program for similar one.
533
microcode: rom32x32 Port map (
534
                                nCS => '0',
535
                                a => uIP(4 downto 0),
536
                                d => uInstruction
537
                        );
538
 
539
cu: sequencer Port map (
540
                                reset => reset,
541
                                clk => clock_main,
542
                                operation => u_opsequence,
543
                                condition => condition,
544
                                directvalue => u_value,
545
                                uIP => uIP
546
                        );
547
 
548
with u_muxa select
549
        alu_a <= X"0000"                                when muxa_zero,
550
                                m                                               when muxa_m,
551
                                arg0(15 downto 0) when muxa_arg0,
552
                                n                                               when muxa_n,
553
                                prod_l                          when muxa_prod,
554
                                i_bcd(15 downto 0)       when muxa_ibcd,
555
                                X"00" & n_bcd(23 downto 16) when muxa_nbcdh,
556
                                n_bcd(15 downto 0)       when others; -- nbcdl
557
 
558
with u_muxb select
559
                alu_b <= u_value(7) & u_value(7) & u_value(7) & u_value(7) & u_value(7) & u_value(7) & u_value(7) & u_value(7) & u_value when muxb_const,
560
                                        m                                               when muxb_m,
561
                                        X"0002"                                 when muxb_two,
562
                                        n                                               when muxb_n,
563
                                        X"0004"                                 when muxb_four,
564
                                        i                                               when muxb_i,
565
                                        remainder                       when muxb_modulo,
566
                                        arg1(15 downto 0) when others;
567
 
568
alu: alu_with_hex2ascii Port map (
569
                                a => alu_a,
570
                                b => alu_b,
571
                                bcdmode => '1',
572
                                operation => u_alu,
573
                                carry_in => u_ci,
574
                                carry_out => alu_c,
575
                                zero => alu_z,
576
                                y => alu_y
577
                        );
578
 
579
update_n: process(clock_main, u_n)
580
begin
581
        if (rising_edge(clock_main)) then
582
                if (u_n = '1') then
583
                        n <= alu_y;
584
                        u_n2bcdstart <= '1'; -- HACKHACK: this signals should be obviously driven by ucode column! 
585
                else
586
                        u_n2bcdstart <= '0';     -- HACKHACK: this signals should be obviously driven by ucode column! 
587
                end if;
588
        end if;
589
end process;
590
 
591
update_i: process(clock_main, u_i)
592
begin
593
        if (rising_edge(clock_main)) then
594
                if (u_i = '1') then
595
                        i <= alu_y;
596
                        u_i2bcdstart <= '1'; -- HACKHACK: this signals should be obviously driven by ucode column! 
597
                else
598
                        u_i2bcdstart <= '0';     -- HACKHACK: this signals should be obviously driven by ucode column! 
599
                end if;
600
        end if;
601
end process;
602
 
603
update_m: process(clock_main, u_m)
604
begin
605
        if (rising_edge(clock_main) and u_m = '1') then
606
                m <= alu_y;
607
        end if;
608
end process;
609
 
610
-- drive multiplier either from microcode or manual input
611
sm_control <=   button(2) & switch(3 downto 1)  when switch(4) = '0' else u_multdiv & u_mode & '0';
612
sm_input0h <=           arg0(31 downto 16)                              when switch(4) = '0' else X"0000";
613
sm_input0l <=           arg0(15 downto 0)                                when switch(4) = '0' else alu_y;
614
sm_input1  <=           arg1(15 downto 0)                                when switch(4) = '0' else m;
615
 
616
        sm: signedmultiplier port map (
617
        reset => Reset,
618
        clk => clock_main,
619
        start => sm_control(3),
620
                  mode => sm_control(2 downto 1),
621
                  dividend32 => sm_control(0),
622
                  arg0h => sm_input0h,
623
        arg0l => sm_input0l, -- fac0 or dividend
624
        arg1 => sm_input1, -- fac1 or divisor
625
        result => result,
626
        ready => sm_ready,
627
                  error => sm_error,
628
        zero => sm_zero,
629
        sign => sm_sign,
630
                  debug => led_bus(19 downto 16)
631
    );
632
 
633
         i2bcd: bin2bcd Port map (
634
                                reset => Reset,
635
                                clk => clock_main,
636
                                start => u_i2bcdstart,
637
                                bin => i,
638
                                ready => i_bcdready,
639
                                bcd => i_bcd,
640
                                debug => open
641
                        );
642
 
643
         n2bcd: bin2bcd Port map (
644
                                reset => Reset,
645
                                clk => clock_main,
646
                                start => u_n2bcdstart,
647
                                bin => n,
648
                                ready => n_bcdready,
649
                                bcd => n_bcd,
650
                                debug => open
651
                        );
652
end;

powered by: WebSVN 2.1.0

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