Search code examples
floating-pointvhdlmultiplicationxilinx-isespartan

Xilinx Floating Point Core - Erroneous 'X' values?


I've attempted to use the Xilinx pg060 Floating Point Core. enter image description here

After looking through the diagrams provided, such as the timing diagram above and the demo testbench (which for the inexperienced such as myself, is quite confusing!) I created a short program that simply multiplies two numbers together.

At first sight, I thought I had done something badly wrong because the result is full of unknown 'X's.

enter image description here

However, after checking many other things as recommended in the user guide, I replaced each 'X' with a '1', and found, this was the correct results.

Is this a) normal or b) my misuse of the core that has just luckily in this instance given me a correct answer?

EDIT: As its most probably my error - why has this occurred?

Thanks very much!

entity FloatMul is
    port(SYSCLK  : IN  STD_LOGIC;
         RESET_N : IN  STD_LOGIC;
         A, B    : IN  FLOAT32;         --input
         E       : OUT FLOAT32          -- E = A*B
    );
end FloatMul;

architecture Behavioral of FloatMul is
    type fsm is (load, ready, waiting, results);
    signal state                  : fsm       := load; --state machine controller
    signal a_val, b_val, prod_val : std_logic := '0'; --valid data flags
    signal prod                   : std_logic_vector(31 downto 0);

    component fp_mul
        port(
            aclk                 : in  std_logic;
            s_axis_a_tvalid      : in  std_logic;
            s_axis_a_tdata       : in  std_logic_vector(31 downto 0);
            s_axis_b_tvalid      : in  std_logic;
            s_axis_b_tdata       : in  std_logic_vector(31 downto 0);
            m_axis_result_tvalid : out std_logic;
            m_axis_result_tdata  : out std_logic_vector(31 downto 0)
        );
    end component;
begin
    fp_core : FP_Mul
        PORT MAP(
            aclk                 => SYSCLK,
            s_axis_a_tvalid      => a_val,
            s_axis_a_tdata       => std_logic_vector(A), --Data from input
            s_axis_b_tvalid      => b_val,
            s_axis_b_tdata       => std_logic_vector(B),
            m_axis_result_tvalid => prod_val,
            m_axis_result_tdata  => prod
        );

    state_machine : process(SYSCLK)
    begin
        if rising_edge(SYSCLK) then
            case state is
                when load =>            --initial state
                    state <= ready;
                when ready =>
                    a_val <= '1';       --set flags to ready
                    b_val <= '1';
                    state <= waiting;
                when waiting =>
                    if prod_val = '1' then
                        a_val <= '0';   --when result ready, remove flags
                        b_val <= '0';
                        state <= results;
                    else
                        state <= waiting; --wait til result ready
                    end if;
                when results =>
                    E     <= float(prod); --cast result to float
                    state <= load;
            end case;
            if RESET_N = '0' then       --synchronous reset
                state <= load;
                a_val <= '0';
                b_val <= '0';
                prod  <= (others => '0');
            end if;
        end if;
    end process;
end Behavioral;

Solution

  • Tour testbench drives the signal prod to zero, which is the output of Xilinx's core. Since there are 2 drivers, where the value driven can't be resolved (such as the core driving 1 and your testbench driving 0), the result is 'X'.

    Just remove the line prod <= (others => '0') and it will work fine!