【问题标题】:Issue in Quartus Post synthesis -- output is obtaining as xxxxxxxxQuartus Post 综合中的问题——输出获取为 xxxxxxxx
【发布时间】:2015-03-31 05:39:19
【问题描述】:

我已经编写了一个 vhdl 代码,我想在 FPGA 中运行它,该代码在 ghdl 和 Quartus 2 预合成(RTL 仿真)中运行良好,但是当我在门级仿真中运行时,它显示data_out as 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 错误...谁能帮助我代码中的问题..我还需要什么更改。提前致谢

-----修改代码

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;

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

预合成 综合后

【问题讨论】:

标签: vhdl fpga quartus


【解决方案1】:

门级仿真包括设计原语(例如触发器)的时序,因此必须遵守触发器数据的设置和保持时间,否则触发器可能会在输出上生成“X”。

测试台代码没有考虑到这一点;例如:

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

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

这可以通过以“慢”时钟运行并且仅更改远离上升沿clk 边缘的数据来解决。这是可以接受的,因为应该通过静态时序分析 (STA) 而不是仿真来验证设计时序;综合后仿真只是为了得到设计OK的好感觉,通过测试用例来验证设计时序是不现实的。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-21
    • 2018-05-22
    • 2011-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多