0

我是 VHDL 的新手。我需要编写一个模块来过滤数据。我的模块结构是:

a_rst - async reset
clk - clock
s_rst - sync reset
valid_in - 0 - no data, 1 - where is data
data_in - [7 downto 0]

输出信号:

valid_out - 0 - no data, 1 - where is data
data_out - [7 downto 0]

我写了testbeanch,它把data_in我的模块放在:00,01,02,03,0A , 02,00,01,02,0F

但我的模块返回:00,01, AA ,03,0A,02,00,01, AA ,0F插入
:00,01, AA ,03,0A,02,00,01, 02 ,0F。

我试图这样做:

--libraries
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
--entity
entity ex6_v03 is
port
(
a_rst     : in std_logic;
clk       : in std_logic;  -- 200 MHz
s_rst     : in std_logic;
valid_in  : in std_logic;
data_in   : in std_logic_vector (7 downto 0);
valid_out : out std_logic;
data_out  : out std_logic_vector (7 downto 0) 
);
end entity ex6_v03;


architecture behavior of ex6_v03 is

signal st : integer := 0;

begin

process(a_rst, clk)
begin
-- asynchronous reset
if (a_rst = '1') then
 data_out <= x"00";
 valid_out <= '0';

-- synchronous reset        
elsif rising_edge(clk) then -- clk
  if (s_rst = '1') then
    valid_out <= '0';
    data_out <= x"00";     
  else                             
    -- normal activity
    if(valid_in = '1') then
      -- main logic
      if(data_in = x"00") then
        st <= 1;
        valid_out <= '1';
        data_out <= data_in;
      elsif(st = 1 and data_in = x"01") then
        st <= 2;
        valid_out <= '1';
        data_out <= data_in;
      elsif(st = 2 and data_in = x"02") then
        st <= 3; 
        valid_out <= '1';
        data_out <= x"AA";
      elsif(st = 3 and data_in = x"03") then
        valid_out <= '1';
        data_out <= data_in;
        st <= 0; 
      else
        st <= 0;
        valid_out <= '1';
        data_out <= data_in;
      end if;

      -- end main logic
    else
      valid_out <= '0';
      data_out <= x"00";   
    end if; 
  end if;
end if;
end process;

end architecture behavior;

但我的模块不等待 0x03 并立即发送 0xAA。如何解决这个问题?

4

1 回答 1

0

您需要添加一个 1 个时钟周期的缓冲区,以便在选择发送 02 还是发送 AA 之前知道下一个输入是否为 03。当然,这意味着输出直到输入后 2 个周期才会出现,而不是只出现一个。查看修改后的代码:

--libraries
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
--entity
entity ex6_v03 is
port
(
a_rst     : in std_logic;
clk       : in std_logic;  -- 200 MHz
s_rst     : in std_logic;
valid_in  : in std_logic;
data_in   : in std_logic_vector (7 downto 0);
valid_out : out std_logic;
data_out  : out std_logic_vector (7 downto 0) 
);
end entity ex6_v03;


architecture behavior of ex6_v03 is

signal st : integer := 0;
signal bvalid : std_logic := '0'; --is buffer valid?
signal data_buffer : std_logic_vector (7 downto 0); --data from previous cycle

begin

process(a_rst, clk)
begin
if (a_rst = '1') then -- asynchronous reset
 data_out <= x"00";
 valid_out <= '0';
 bvalid <= '0';

elsif rising_edge(clk) then -- clk
  if (s_rst = '1') then --sync reset
    valid_out <= '0';
    bvalid <= '0';
    data_out <= x"00";     
  else -- normal activity  

    if(valid_in = '1') then --fill buffer

      if(data_in = x"00") then
        st <= 1;
        data_out <= data_in;
      elsif(st = 1 and data_in = x"01") then
        st <= 2;
        data_out <= data_in;
      elsif(st = 2 and data_in = x"02") then
        st <= 3; 
      else
        st <= 0;
      end if;  

      data_buffer <= data_in;
      bvalid <= '1';
    else
      bvalid <= '0';   
    end if; 

    if(bvalid = '1') then --use buffer to populate output
        valid_out <= '1'
        if(st = 3 and data_in = x"03" and valid_in = '1') then --EDIT: make sure the x"03" sitting on the input is actually valid
          data_out <= x"AA"; --output for the previous cycle (buffer contains x"02")
        else
          data_out <= data_buffer;
        end if
    else
      valid_out <= '0';
      data_out <= x"00";
    end if;

  end if;
end if;
end process;

end architecture behavior;
于 2013-10-07T04:11:29.763 回答