Quartus 中的问题 Post 综合——输出为 xxxxxxxx

Issue in Quartus Post synthesis -- output is obtaining as xxxxxxxx

我写了一个 vhdl 代码,我想 运行 它在 FPGA 中,代码在 ghdl 和 Quartus 2 预综合(RTL 仿真)中工作正常,但是当我 运行ning 在门级模拟中,它显示 data_out 为 xxxxxxx。我不知道是什么问题。谁能帮帮我?

--- 设备代码

   library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity SimpleCalculator is
port ( data_in :in std_logic_vector(3 downto 0);
data_valid : in std_logic;
data_out : out std_logic_vector(7 downto 0);
clk, reset: in std_logic);
end entity SimpleCalculator;


architecture behave of SimpleCalculator is
----------------------------------
-- defining main state consisting of states of main thread
----------------------------------
type main_state is (main_idle,main_read0,main_read1,main_read2,main_read3,main_read4,main_calc);
signal next_mainstate: main_state;


-- below code creates two dimensional
-- array of 8 inputs with 16 bits each

type inputs_bit is array(0 to 4) of std_logic_vector(3 downto 0);
signal input_array : inputs_bit;

signal calc_start : std_logic;
signal calc_done : std_logic;


------------------------------
-- defining signals and states for calc thread
------------------------------
type calc_state is (calc_idle,calc_check_inputs,calc_running,calc_error);
signal calcstate : calc_state;

-----------------------------
begin
main: process(clk,reset,data_valid,next_mainstate,calc_done)
variable nstate:main_state;
--variable count: integer:=0;
begin
nstate := next_mainstate;
case next_mainstate is

    when main_idle =>
    if(data_valid = '1' ) then
    nstate:= main_read0;
    else
    nstate:= main_idle;
    end if;

    when main_read0 =>
    input_array(0) <= data_in;
    nstate:=main_read1;

    when main_read1 =>
    input_array(1) <= data_in;
    nstate:=main_read2;

    when main_read2 =>
    input_array(2) <= data_in;
    nstate:=main_read3;

    when main_read3 =>
    input_array(3) <= data_in;
    nstate:=main_read4;

    when main_read4 =>
    input_array(4) <= data_in;
    nstate:=main_calc;
    calc_start <= '1';

    when main_calc =>
    calc_start <= '0';
    if(calc_done ='1') then
    nstate:= main_idle;
    else
    nstate:=main_calc;
    end if;

    when others => null;
    end case; 

if(clk'event and clk = '1') then
      if(reset = '1') then
        next_mainstate <= main_idle;
      else
        next_mainstate <= nstate;
      end if;
    end if;
  end process main;

------------------------------------------------
--calc fsm
---------------------------------------------
calc: process(clk,reset,calc_start,calcstate)
variable nstate:calc_state;
begin
nstate := calcstate;

case calcstate is 

    when calc_idle =>
    if(calc_start = '1') then
    nstate := calc_check_inputs;
    else
    nstate := calc_idle;
    end if;

    when calc_check_inputs =>
    if(input_array(0) = "1010" and input_array(1) < "1010" and input_array(2) > "1011"
    and input_array(3) < "1010" and input_array(4) = "1011") then
    nstate := calc_running;
    else
    nstate := calc_error;
    end if;

    -- check for correct sequence 

    when calc_error =>
    data_out <= "11111111";

    when calc_running =>
    case input_array(2) is
        when "1100" =>
        data_out <= std_logic_vector(unsigned(input_array(1)) * unsigned(input_array(3)) ) after 1 ns;
        when "1101" =>
        data_out <= "0000" & std_logic_vector(unsigned(input_array(1)) + unsigned(input_array(3)) ) after 1 ns;
        when "1110" =>
        data_out <= "0000" & std_logic_vector(unsigned(input_array(1)) - unsigned(input_array(3)) ) after 1 ns;
        when "1111" =>
        data_out <= "0000" & std_logic_vector(unsigned(input_array(1)) / unsigned(input_array(3)) ) after 1 ns;
        when others => null;
    end case;
    calc_done <='1';
    nstate := calc_idle;

    when others => null;
end case;

if(clk'event and clk = '1') then
      if(reset = '1') then
        calcstate <= calc_idle;
      else
        calcstate <= nstate;
      end if;
    end if;
  end process calc;
end behave;







--- **testbench**




 library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;

    library std;
    use std.textio.all;

    entity Simplecalculator_tb is
    end entity;

    architecture behave of Simplecalculator_tb is
    signal data_in : std_logic_vector(3 downto 0);
    signal data_valid : std_logic:= '0';
    signal data_out : std_logic_vector(7 downto 0);
    signal clk, reset: std_logic:= '0';

    file stimulus_file: text is in "calci_inputs.txt";
    file result_file: text is in "calci_result.txt";

        component SimpleCalculator is
        port ( data_in :in std_logic_vector(3 downto 0);
        data_valid : in std_logic;
        data_out : out std_logic_vector(7 downto 0);
        clk, reset: in std_logic);
        end component;

        begin

          -- 10 ns clock.
          clk <= not clk after 5 ns;

          process
            variable L: line;
            variable next_number_input: bit_vector(3 downto 0);
            variable next_number_output: bit_vector(7 downto 0);

          begin

            reset <= '1';
            data_valid <= '0';
            wait until clk ='1';
            reset <= '0';

            data_valid <= '1';
            wait until clk ='1';
            data_valid <= '0';

            while( not endfile(stimulus_file)) loop
              readline(stimulus_file,L);
              read(L,next_number_input);

              data_in <= To_StdLogicVector(next_number_input);
            wait until clk='1';
            assert false report "Sent item " severity note;

            end loop;

            assert false report "Sent all items " severity note;

            wait for 20 ns;
            assert false report "Received done " severity note;

                readline(result_file,L);
                read(L,next_number_output);
                if(data_out = To_StdLogicVector(next_number_output)) then
                  assert false report "SUCCESS: got the correct result." severity note;
                else
                  assert false report "FAILURE: incorrect result! " severity ERROR;
                end if;

                wait;
              end process;  

        dut : SimpleCalculator port map
            ( data_in => data_in, data_valid => data_valid, data_out => data_out, clk => clk,
            reset => reset);

        end behave;

---输入文件 1010 0111 1110 0010 1011

--输出文件内容 00000101


我已经更改了我的代码和测试台,我什至包括了延迟,但我仍然遇到相同的 xxxx 错误...任何人都可以帮助我代码中的错误...我还有什么需要提前change.Thanks

------修改代码

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity SimpleCalculator is
port ( data_in :in std_logic_vector(3 downto 0);
data_valid : in std_logic;
data_out : out std_logic_vector(7 downto 0);
clk, reset: in std_logic);
end entity SimpleCalculator;


architecture behave of SimpleCalculator is
----------------------------------
-- defining main state consisting of states of main thread
----------------------------------
type main_state is (main_idle,main_read0,main_read1,main_read2,main_read3,main_read4,main_calc);
signal next_mainstate: main_state;


-- below code creates two dimensional
-- array of 8 inputs with 16 bits each

type inputs_bit is array(0 to 4) of std_logic_vector(3 downto 0);
signal input_array : inputs_bit;

signal calc_start : std_logic;
signal calc_done : std_logic;


------------------------------
-- defining signals and states for calc thread
------------------------------
type calc_state is (calc_idle,calc_check_inputs,calc_running,calc_error);
signal calcstate : calc_state;

-----------------------------
begin
main: process(clk,reset,data_valid,next_mainstate,calc_done)
variable nstate:main_state;
--variable count: integer:=0;
begin
nstate := next_mainstate;
case next_mainstate is

    when main_idle =>
    if(data_valid = '1' ) then
    nstate:= main_read0;
    else
    nstate:= main_idle;
    end if;

    when main_read0 =>
    input_array(0) <= data_in after 2 ns;
    nstate:=main_read1;

    when main_read1 =>
    input_array(1) <= data_in after 2 ns;
    nstate:=main_read2; 

    when main_read2 =>
    input_array(2) <= data_in after 2 ns;
    nstate:=main_read3;

    when main_read3 =>
    input_array(3) <= data_in after 2 ns;
    nstate:=main_read4;

    when main_read4 =>
    input_array(4) <= data_in after 2 ns;
    nstate:=main_calc; 
    calc_start <= '1' after 2 ns;

    when main_calc =>
    calc_start <= '0' after 2 ns;
    if(calc_done ='1') then
    nstate:= main_idle;
    else
    nstate:=main_calc;
    end if;

    when others => null;
    end case; 

if(clk'event and clk = '1') then
      if(reset = '1') then
        next_mainstate <= main_idle;
      else
        next_mainstate <= nstate;
      end if;
    end if;
  end process main;

------------------------------------------------
--calc fsm
---------------------------------------------
calc: process(clk,reset,calc_start,calcstate)
variable nstate:calc_state;
begin
nstate := calcstate;

case calcstate is 

    when calc_idle =>
    if(calc_start = '1') then
    nstate := calc_check_inputs;
    else
    nstate := calc_idle;
    end if;

    when calc_check_inputs =>
    if(input_array(0) = "1010" and input_array(1) < "1010" and input_array(2) > "1011"
    and input_array(3) < "1010" and input_array(4) = "1011") then
    nstate := calc_running;
    else
    nstate := calc_error;
    end if;

    -- check for correct sequence 

    when calc_error =>
    data_out <= "11111111";

    when calc_running =>
    case input_array(2) is
        when "1100" =>
        data_out <= std_logic_vector(unsigned(input_array(1)) * unsigned(input_array(3)) ) after 1 ns;
        when "1101" =>
        data_out <= "0000" & std_logic_vector(unsigned(input_array(1)) + unsigned(input_array(3)) ) after 1 ns;
        when "1110" =>
        data_out <= "0000" & std_logic_vector(unsigned(input_array(1)) - unsigned(input_array(3)) ) after 1 ns;
        when "1111" =>
        data_out <= "0000" & std_logic_vector(unsigned(input_array(1)) / unsigned(input_array(3)) ) after 1 ns;
        when others => null;
    end case;
    calc_done <='1' after 2 ns;
    nstate := calc_idle;

    when others => null;
end case;

if(clk'event and clk = '1') then
      if(reset = '1') then
        calcstate <= calc_idle;
      else
        calcstate <= nstate;
      end if;
    end if;
  end process calc;
end behave;

-- 新测试平台

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library std;
use std.textio.all;

entity Simplecalculator_tb is
end entity;

architecture behave of Simplecalculator_tb is
signal data_in : std_logic_vector(3 downto 0):= (others => '0');
signal data_valid : std_logic:= '0';
signal data_out : std_logic_vector(7 downto 0);
signal clk, reset: std_logic:= '0';

file stimulus_file: text is in "/home/student/pavanpalla/lab_5/calci_inputs.txt";
file result_file: text is in "/home/student/pavanpalla/lab_5/calci_result.txt";

component SimpleCalculator is
port ( data_in :in std_logic_vector(3 downto 0);
data_valid : in std_logic;
data_out : out std_logic_vector(7 downto 0);
clk, reset: in std_logic);
end component;

begin

  -- 10 ns clock.
  clk <= not clk after 20 ns;

  process
    variable L: line;
    variable next_number_input: bit_vector(3 downto 0);
    variable next_number_output: bit_vector(7 downto 0);

  begin

    reset <= '1';
    data_valid <= '0';
    wait until clk ='1';
    reset <= '0' after 2 ns;

    data_valid <= '1' after 2 ns;
    wait until clk ='1';
    data_valid <= '0' after 2 ns;

    while( not endfile(stimulus_file)) loop
      readline(stimulus_file,L);
      read(L,next_number_input);

      data_in <= To_StdLogicVector(next_number_input) after 10 ns;
    wait until clk='1';
    assert false report "Sent item " severity note;

    end loop;

    assert false report "Sent all items " severity note;

    wait for 50 ns;
    assert false report "Received done " severity note;

        readline(result_file,L);
        read(L,next_number_output);
        if(data_out = To_StdLogicVector(next_number_output)) then
          assert false report "SUCCESS: got the correct result." severity note;
        else
          assert false report "FAILURE: incorrect result! " severity ERROR;
        end if;

        wait;
      end process;  

dut : SimpleCalculator port map
    ( data_in => data_in, data_valid => data_valid, data_out => data_out, clk => clk,
    reset => reset);

end behave;

我还附上了合成前和合成后的图像。我无法弄清楚我哪里出错了

预合成 post_synthesis

门级仿真包括设计基元的时序,例如 flip-flops,因此必须遵守 flip-flops 数据的建立和保持时间,否则翻转-flops 可能会在输出上生成 'X'。

test bench代码写的时候没有考虑到这一点;例如:

wait until clk ='1';
reset <= '0';

resetclk 的上升沿之后被移除 0 ps,并且根据实现,同步设计可能有保持时间要求 reset .

这可以通过 运行 在 "slow" 时钟上解决,并且仅从 clk 上升沿更改数据 "far"。这是可以接受的,因为设计时序应该通过静态时序分析 (STA) 而不是仿真来验证; post-synthesis simulation只是为了获得设计OK的好感,但是通过test case来验证设计时序是不现实的。

您还可以考虑将进程编写为时钟进程或组合进程,因为这通常会使设计更易于编写、读取和调试。 calc 过程是在 clk 的上升沿和 calcstate.

的上升沿更新的过程示例