I am trying to implement on a Basys3 a MMX ALU. All operations work great, except multiplication. I am using Booth’s algorithm and for now I am trying to turn on a LED to let me know when the cycle is done( by that I mean when the result is valid). In the waveform simulation, the signal gets turn on, but on the fpga it does not. Any idea why?
MMX ALU component:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.std_logic_unsigned.all;
entity MMXAlu is
Port (
clk : in std_logic;
--value1 : out std_logic_vector(63 downto 0);
--value2 : out std_logic_vector(63 downto 0);
--s: out std_logic_vector(63 downto 0);
reset : in std_logic;
opcode : in std_logic_vector(4 downto 0);
--en : in std_logic;
--sw : in std_logic_vector(15 downto 0);
addr1 : in std_logic_vector(4 downto 0);
addr2 : in std_logic_vector(4 downto 0);
--cout : out std_logic;
--opAdder : out std_logic_vector(18 downto 0);
--opLogical : out std_logic;
--opCompare : out std_logic_vector(1 downto 0);
--opConv : out std_logic;
--opShift : out std_logic_vector (1 downto 0);
--opPerformed : out std_logic_vector(2 downto 0);
s : out std_logic_vector(63 downto 0);
cycle_done : out std_logic
);
end MMXAlu;
architecture Behavioral of MMXAlu is
signal a : std_logic_vector(63 downto 0);
signal b : std_logic_vector(63 downto 0);
signal operationPerformed : std_logic_vector(2 downto 0) := (others => '0');
signal selOrAnd : std_logic := '0';
signal operationsCompare : std_logic_vector(1 downto 0) := (others => '0');
signal operationsConv : std_logic := '0';
signal operationsShift : std_logic_vector(1 downto 0) := (others => '0');
signal operationsAdder : std_logic_vector(18 downto 0) := (others => '0');
signal resultLogical : std_logic_vector(63 downto 0);
signal resultConv : std_logic_vector(63 downto 0);
signal resultComp : std_logic_vector(63 downto 0);
signal resultShift : std_logic_vector(63 downto 0);
signal resultAddition : std_logic_vector(63 downto 0);
signal resultMul : std_logic_vector(63 downto 0);
signal couttemp : std_logic;
signal result : std_logic_vector(63 downto 0);
signal nr_aux : std_logic_vector(63 downto 0);
signal activate_anode : std_logic_vector(3 downto 0) := "0111";
signal counter : std_logic_vector(1 downto 0) := (others => '0');
signal lcd_number : std_logic_vector(3 downto 0);
signal slow_clk : std_logic := '0';
signal clk_div : std_logic_vector(26 downto 0) := (others => '0');
signal byte : std_logic_vector(15 downto 0);
signal test,test1 : std_logic;
component rom is
generic(
address_length : natural := 5;
data_length : natural := 64
);
Port (
clk : in std_logic;
en : in std_logic;
addr1 : in std_logic_vector( (address_length - 1) downto 0);
addr2 : in std_logic_vector( (address_length - 1) downto 0);
data_output1: out std_logic_vector( (data_length-1) downto 0);
data_output2: out std_logic_vector( (data_length-1) downto 0)
);
end component;
component ControlUnit is
Port(
opcode : in std_logic_vector(4 downto 0);
selOrAnd : out std_logic;
operationsAdder : out std_logic_vector(18 downto 0);
operationsCompare : out std_logic_vector(1 downto 0);
operationsConv : out std_logic;
operationsShift : out std_logic_vector (1 downto 0);
operationPerformed : out std_logic_vector(2 downto 0)
);
end component;
component logicinstrMMX is
Port ( a : in std_logic_vector(63 downto 0);
b : in std_logic_vector(63 downto 0);
operation : in std_logic;
s : out std_logic_vector(63 downto 0)
);
end component;
component compareinstr is
Port (
a : in std_logic_vector(63 downto 0);
b : in std_logic_vector(63 downto 0);
operation : in std_logic_vector(1 downto 0);
s : out std_logic_vector(63 downto 0)
);
end component;
component conversioninstr is
Port (
a : in std_logic_vector(63 downto 0);
b : in std_logic_vector(63 downto 0);
operation : in std_logic;
output : out std_logic_vector(63 downto 0)
);
end component;
component mux5to1_64bit is
Port (
data0 : in std_logic_vector(63 downto 0); -- Data input 0
data1 : in std_logic_vector(63 downto 0); -- Data input 1
data2 : in std_logic_vector(63 downto 0); -- Data input 2
data3 : in std_logic_vector(63 downto 0); -- Data input 3
data4 : in std_logic_vector(63 downto 0);
data5 : in std_logic_vector(63 downto 0); -- Data input 4
sel : in std_logic_vector(2 downto 0); -- Select input (3 bits)
y : out std_logic_vector(63 downto 0) -- Output
);
end component;
component shifts is
Port (
a: in std_logic_vector(63 downto 0);
shiftValue : in std_logic_vector(63 downto 0);
operation : in std_logic_vector(1 downto 0);
s: out std_logic_vector(63 downto 0)
);
end component;
component adderMMX IS
PORT (
a : in std_logic_vector(63 downto 0);
b : in std_logic_vector(63 downto 0);
operation : in std_logic_vector(18 downto 0);
-- Outputs
s : out std_logic_vector(63 downto 0);
--underflow : out std_logic;
cout : out std_logic
);
END component;
component multiplicationInstructions is
Port (a: in std_logic_vector(63 downto 0);
b : in std_logic_vector(63 downto 0);
clk : in std_logic;
reset : in std_logic;
p : out std_logic_vector(63 downto 0);
cycle_done : out std_logic );
end component;
begin
memory: rom port map(
clk => clk,
en => '1',
addr1 => addr1,
addr2 => addr2,
data_output1 => a,
data_output2 =>b
);
co : ControlUnit port map(
opcode => opcode,
selOrAnd => selOrAnd,
operationsCompare => operationsCompare,
operationsConv => operationsConv,
operationsShift => operationsShift,
operationsAdder => operationsAdder,
operationPerformed => operationPerformed
);
logicinstructions : logicinstrMMX port map(
a => a,
b => b,
operation => selOrAnd,
s => resultLogical
);
compareinstructions : compareinstr port map(
a => a,
b => b,
operation => operationsCompare,
s => resultComp
);
conversioninstructions : conversioninstr port map(
a => a,
b => b,
operation => operationsConv,
output => resultConv
);
shiftinstructions : shifts port map(
a => a,
shiftValue => b,
operation => operationsShift,
s => resultShift
);
adders : adderMMX port map(
a => a,
b => b,
operation => operationsAdder,
s => resultAddition,
cout => test
);
multiplication: multiplicationInstructions port map(
a => a,
b => b,
clk => clk,
reset => reset,
p => resultMul,
cycle_done => cycle_done
);
mux5to1 : mux5to1_64bit port map(
data0 => resultAddition,
data1 => resultComp,
data2 => resultConv,
data3 => resultLogical,
data4 => resultShift,
data5 => resultMul,
sel => operationPerformed,
y => result
);
--opAdder <= operationsAdder;
--opCompare <= operationsCompare;
--opConv <= operationsConv;
--opShift <= operationsShift;
--opLogical <= selOrAnd;
--opPerformed <= operationPerformed;
--value1 <= a;
--value2 <= b;
s <= result;
end Behavioral;
SSD component:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.std_logic_unsigned.all;
entity SSD is
Port (
nr_aux : in std_logic_vector(63 downto 0);
clk : in std_logic;
btn : in std_logic;
seg : out std_logic_vector(6 downto 0);
an : out std_logic_vector(3 downto 0)
);
end SSD;
architecture Behavioral of SSD is
signal activate_anode : std_logic_vector(3 downto 0) := "0111";
signal counter : std_logic_vector(1 downto 0) := (others => '0');
signal lcd_number : std_logic_vector(3 downto 0);
signal slow_clk : std_logic := '0';
signal clk_div : std_logic_vector(16 downto 0) := (others => '0');
signal byte : std_logic_vector(15 downto 0);
signal counter2 : std_logic_vector(1 downto 0) := (others => '0');
signal btn_reg : std_logic := '0'; -- Register for btn signal
signal btn_rising_edge : std_logic := '0'; -- Edge detection signal
begin
-- Clock divider to create slow clock
process(clk)
begin
if rising_edge(clk) then
clk_div <= clk_div + 1;
if clk_div = "11000011010100000" then -- Divide 100 MHz to ~1 kHz
slow_clk <= not slow_clk;
clk_div <= (others => '0');
end if;
end if;
end process;
--counter for displaying every 4 bytes
-- Detect rising edge of btn
process(clk)
begin
if rising_edge(clk) then
btn_rising_edge <= not btn_reg and btn; -- Detect rising edge
btn_reg <= btn; -- Update btn register
end if;
end process;
-- Update counter2 on btn rising edge
process(clk)
begin
if rising_edge(clk) then
if btn_rising_edge = '1' then
counter2 <= counter2 + 1;
if (counter2 = "11") then
counter2 <= "00";
end if;
end if;
end if;
end process;
-- Counter for multiplexing
process(slow_clk)
begin
if rising_edge(slow_clk) then
counter <= counter + 1;
end if;
end process;
-- Activate anode based on counter
process(counter)
begin
case counter is
when "00" =>
activate_anode <= "0111";
lcd_number <= byte(15 downto 12);
when "01" =>
activate_anode <= "1011";
lcd_number <= byte(11 downto 8);
when "10" =>
activate_anode <= "1101";
lcd_number <= byte(7 downto 4);
when "11" =>
activate_anode <= "1110";
lcd_number <= byte(3 downto 0);
when others =>
activate_anode <= "1111"; -- All OFF (should not happen)
end case;
end process;
process(counter2)
begin
case counter2 is
when "00" => byte <= nr_aux(15 downto 0);
when "01" => byte <= nr_aux(31 downto 16);
when "10" => byte <= nr_aux(47 downto 32);
when "11" => byte <= nr_aux(63 downto 48);
when others => byte <= (others => '0');
end case;
end process;
-- Assign `an` to activate anodes
an <= activate_anode;
-- Assign segment values based on lcd_number
process(lcd_number)
begin
case lcd_number is
when "0000" => seg <= "1000000"; -- "0"
when "0001" => seg <= "1111001"; -- "1"
when "0010" => seg <= "0100100"; -- "2"
when "0011" => seg <= "0110000"; -- "3"
when "0100" => seg <= "0011001"; -- "4"
when "0101" =>seg <= "0010010"; -- "5"
when "0110" => seg <= "0000010"; -- "6"
when "0111" => seg <= "1111000"; -- "7"
when "1000" => seg <= "0000000"; -- "8"
when "1001" => seg <= "0010000"; -- "9"
when "1010" => seg <= "0001000"; -- "A"
when "1011" => seg <= "0000011"; -- "b"
when "1100" => seg <= "1000110"; -- "C"
when "1101" => seg <= "0100001"; -- "d"
when "1110" => seg <= "0000110"; -- "E"
when "1111" => seg <= "0001110"; -- "F"
when others => seg <= "1111111"; -- Blank display
end case;
end process;
end Behavioral;
Top level component:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.std_logic_unsigned.all;
entity toplevel is
Port (
sw : in std_logic_vector(15 downto 0);
btnU : in std_logic;
clk : in std_logic;
seg : out std_logic_vector(6 downto 0);
LED : out std_logic_vector(1 downto 0);
an : out std_logic_vector(3 downto 0)
);
end toplevel;
architecture Behavioral of toplevel is
signal result : std_logic_vector(63 downto 0);
signal temp : std_logic;
signal slow_clk : std_logic := '0';
signal clk_div : std_logic_vector(26 downto 0) := (others => '0');
component SSD is
Port (
nr_aux : in std_logic_vector(63 downto 0);
clk : in std_logic;
btn : in std_logic;
seg : out std_logic_vector(6 downto 0);
an : out std_logic_vector(3 downto 0)
);
end component;
component MMXAlu is
Port (
clk : in std_logic;
reset : in std_logic;
opcode : in std_logic_vector(4 downto 0);
addr1 : in std_logic_vector(4 downto 0);
addr2 : in std_logic_vector(4 downto 0);
s : out std_logic_vector(63 downto 0);
cycle_done : out std_logic
);
end component;
begin
alu: MMXAlu port map(
clk => clk,
reset => sw(15),
opcode => sw(14 downto 10),
addr1 => sw(4 downto 0),
addr2 => sw(9 downto 5),
cycle_done => led(0),
s => result);
display: SSD port map(
clk => clk,
nr_aux => result,
btn => btnU,
an => an,
seg => seg);
LED(1) <= '1';
--LED <= temp;
end Behavioral;
If nothing seems wrong here, I can also post my Booth’s implementation, but as I said, on the simulation it works fine and my goal so far is to get that led turned on.