Close

Running serial CPU at 25MHz!

A project log for Bit-serial CPU based on crossbar switch

256 switches and few shift registers to implement a working 16 or 32-bit integer arithmetic calculator (+, -, *, /, isqrt, BCD / bin conv..)

zpekiczpekic 09/06/2022 at 04:400 Comments

As noted in other logs, it was difficult to run the CPU at >2MHz or so, most likely due to R/L/C impedances and skewed signals from 6+ in wires from the PMODs to breadboard holding the 2 physical MT8816 ICs.

But what if the switch matrix was inside the FPGA, not outside, how fast could it run? To try that out, I developed a "virtual replacement" for the 16*16 switch matrix, and called it (very original!) MT16x16

Replacing a true analog switch array with FPGA would be only possible using very fancy and expensive FPGA chips which have analog paths. Luckily, MT8816 in this design is used as a "wired or" not really analog, so it is possible to create 256 D-type flip-flops, each controlling an AND gate connected to a row input (X), and 16 of these OR'd together make up a column output (Y):

Noted on the schema above:

In VHDL code, this 16*16 matrix is generated and interconnected using 2 generate loops. The column Y OR is pulled out of inner loop to make sure all ANDs are parallel and not stacked serially.

With external wires eliminated, CPU can be driven up to 25MHz clock frequency (microcode execution at 6.25MHz due to 4 phase clock). This means that an integer square root of 32-bit number takes typically 16305 to 94195 cycles which means 2.6 to 15ms.

CPU frequency is selected using switches 2..0 on the FPGA board. This gives 8 choices, the upper 4 of which select operation using internal matrix, and lower 4 with external (slower, but more fun!) MT8816 chips:

-- select the clock
with sw_clksel select mt_cnt <= 
    ss_cnt    when "000",    -- single step
    freq_2048(9 downto 8) when "001",    -- 4Hz        -- EXTERNAL MT8816
    freq_2048(5 downto 4) when "010",    -- 64Hz        -- EXTERNAL MT8816
    freq_50M(5 downto 4) when "011",    -- 1.5625MHz     -- EXTERNAL MT8816
    freq_50M(4 downto 3) when "100",    -- 3.125MHz    -- INTERNAL MT16x16
    freq_50M(3 downto 2) when "101",    -- 6.25MHz    -- INTERNAL MT16x16
    freq_50M(2 downto 1) when "110",    -- 12.5MHz    -- INTERNAL MT16x16
    freq_50M(1 downto 0) when others;    -- 25MHz     -- INTERNAL MT16x16

Given that state of the matrix is reset and changed during the instruction execution (in other words, switch matrix state does not contain data to preserve from one operation to the next), it is possible to switch use of internal/external and back between instructions. Theoretically, it could be possible even to change the use while calculating an operation (because switch on/off commands are sent to both matrices regardless of which one is in use), but I haven't tried it and might fail due to glitches during such switch.

Discussions