2015-06-03 4 views
3

Я работаю над небольшим проектом по изучению VHDL. В настоящее время я работаю над конвертером BCD (преобразование двоичного кода в его номер BCD).Сброс вывода после запуска

Но я застрял при внедрении испытательного стенда. Он не сбрасывает выходные данные после применения шаблонов.

Мой VHDL код объекта:

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

entity bcd_mod is 
     port (
       entry: in std_logic_vector(16 downto 0); 
       outp: out std_logic_vector(20 downto 0) 
     ); 
end bcd_mod; 

architecture calculate of bcd_mod is 

begin 
     process(entry) 
       variable outp_cp : std_logic_vector(20 downto 0) := (others => '0'); 
       variable place : integer := 1; 
       variable digit : integer := 0; 
       variable number : integer := 0; 

       begin 

         for i in 16 downto 0 loop 
           case entry(i) is 
             when '0' => null; 
             when '1' => number := number + (2**i); 
             when others => null; 
           end case; 
         end loop; 

         if number > 99999 then 
           outp_cp(20) := '1'; 
         else 
           while (number > 0) loop 
             digit := number mod 10; 

             if place = 1 then 
               outp_cp(3 downto 0) := std_logic_vector(to_unsigned(digit, 4)); 
             elsif place = 2 then 
               outp_cp(7 downto 4) := std_logic_vector(to_unsigned(digit, 4)); 
             elsif place = 3 then 
               outp_cp(11 downto 8) := std_logic_vector(to_unsigned(digit, 4)); 
             elsif place = 4 then 
               outp_cp(15 downto 12) := std_logic_vector(to_unsigned(digit, 4)); 
             else 
               outp_cp(19 downto 16) := std_logic_vector(to_unsigned(digit, 4)); 
             end if; 

             number := number - digit; 
             number := number/10; 
             place := place + 1; 
           end loop; 
         end if; 

         outp <= outp_cp; 
         outp_cp := (others => '0'); 

     end process; 

end calculate; 

Мой испытательный стенд для кода:

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

entity bcd_mod_testbench is 
end bcd_mod_testbench; 

architecture calculate of bcd_mod_testbench is 
     component bmt 
       port(entry : in std_logic_vector(16 downto 0); outp : out std_logic_vector(20 downto 0)); 
     end component; 

     for bmt_0: bmt use entity work.bcd_mod; 
       signal entry : std_logic_vector(16 downto 0); 
       signal outp : std_logic_vector(20 downto 0); 
       begin 

     bmt_0: bmt port map (entry => entry, outp => outp); 

     process 
       type pattern_type is record 
         entry : std_logic_vector(16 downto 0); 
         outp : std_logic_vector(20 downto 0); 
       end record; 

       type pattern_array is array (natural range <>) of pattern_type; 
       constant patterns : pattern_array := 
       (("00000110111101101", "000000011010101100101"), 
       ("00000000000000011", "000000000000000000011"), 
       ("00000000000011011", "000000000000000100111")); 
       begin 

       for i in patterns'range loop 

         entry <= patterns(i).entry; 

         wait for 1 ns; 

         assert outp = patterns(i).outp 
         report "Wrong BCD number." severity error; 
       end loop; 

       assert false report "End of test." severity note; 
       wait; 
     end process; 
end calculate; 

А вот выход в GTKWave. Вы можете видеть здесь, что после запуска кода с большим номером начинаются номера, начиная с которых число заканчивается.

GTKWave output from testbench (кликабельны)

Надежда, чтобы получить какие-либо советы, чтобы решить эту проблему.

ответ

2

В VHDL variable сохраняет свою ценность между переходом процесса. Таким образом, когда вы вводите процесс для номера X"000003", все ваши переменные все еще имеют значение, которое они добавляют в конце обработки X"003565".

Быстрый тест показывает, что установка place к 1 в начале процесса исправляет проблему:

process(entry) 
    variable outp_cp : std_logic_vector(20 downto 0) := (others => '0'); 
    variable place : integer := 1; 
    variable digit : integer := 0; 
    variable number : integer := 0; 
begin 
    place := 1; 

    ... 
+0

Ой хорошо, в этом была проблема. Большое спасибо за разъяснение проблемы с переменной. Я думаю, сигналы не сделали бы эту ошибку, так как обычно они назначаются _after_ процесс закончился, правильно? – CRoemheld

+0

Да, сигнал принимает новое значение после процесса или когда процесс встречает оператор ожидания. –

2

Ваша проблема заключается в немаркированной процесса в bcd_mod. Вы не инициализируетесь place 1 на каждой новой записи:

architecture calculate of bcd_mod is 

begin 
unlabeled: 
    process(entry) 
     variable outp_cp: std_logic_vector(20 downto 0) := (others => '0'); 
     variable place: integer := 1; 
     variable digit: integer := 0; 
     variable number: integer := 0; 
    begin 
     place := 1; -- ADDED 
     for i in 16 downto 0 loop 

И проблема становится очевидной, если вы посмотрите на двоичных значениях, которые я сделал с statments отчета в вашем тестбенче:

architecture foo of bcd_mod_testbench is 
    component bmt 
     port (
      entry: in std_logic_vector(16 downto 0); 
      outp: out std_logic_vector(20 downto 0) 
     ); 
    end component; 
    for bmt_0: bmt use entity work.bcd_mod; 
    signal entry: std_logic_vector(16 downto 0); 
    signal outp: std_logic_vector(20 downto 0); 

    function to_string(inp: std_logic_vector) return string is 
     variable image_str: string (1 to inp'length); 
     alias input_str: std_logic_vector (1 to inp'length) is inp; 
    begin 
     for i in input_str'range loop 
      image_str(i) := character'VALUE(std_ulogic'IMAGE(input_str(i))); 
     end loop; 
     return image_str; 
    end; 
begin 

bmt_0: 
    bmt 
     port map (
      entry => entry, 
      outp => outp 
     ); 

unlabeled: 
    process 
     type pattern_type is record 
      entry: std_logic_vector(16 downto 0); 
      outp: std_logic_vector(20 downto 0); 
     end record; 

     type pattern_array is array (natural range <>) of pattern_type; 
     constant patterns: pattern_array := (
      ("00000110111101101", "000000011010101100101"), 
      ("00000000000000011", "000000000000000000011"), 
      ("00000000000011011", "000000000000000100111") 
     ); 
    begin 
     for i in patterns'range loop 
      entry <= patterns(i).entry; 
      wait for 1 ns; 
      assert outp = patterns(i).outp 
      report "Wrong BCD number pattern (" & integer'image(i) & ")" 
      severity error; 
      report "entry = " & to_string(entry); 
      report "outp = " & to_string(outp); 
     end loop; 
     assert false report "End of test." severity note; 
     wait; 
    end process; 
end architecture; 

Который дает:

bcd_mod_tb.vhdl:119:13:@1ns:(report note): entry = 00000110111101101
bcd_mod_tb.vhdl:120:13:@1ns:(report note): outp = 000000011010101100101
bcd_mod_tb.vhdl:116:13:@2ns:(assertion error): Wrong BCD number pattern (1)
bcd_mod_tb.vhdl:119:13:@2ns:(report note): entry = 00000000000000011
bcd_mod_tb.vhdl:120:13:@2ns:(report note): outp = 000110000000000000000
bcd_mod_tb.vhdl:116:13:@3ns:(assertion error): Wrong BCD number pattern (2)
bcd_mod_tb.vhdl:119:13:@3ns:(report note): entry = 00000000000011011
bcd_mod_tb.vhdl:120:13:@3ns:(report note): outp = 000100000000000000000
bcd_mod_tb.vhdl:122:9:@3ns:(assertion note): End of test.

И когда место инициализируется, нет ошибки:

bcd_mod_tb.vhdl:119:13:@1ns:(report note): entry = 00000110111101101
bcd_mod_tb.vhdl:120:13:@1ns:(report note): outp = 000000011010101100101
bcd_mod_tb.vhdl:119:13:@2ns:(report note): entry = 00000000000000011
bcd_mod_tb.vhdl:120:13:@2ns:(report note): outp = 000000000000000000011
bcd_mod_tb.vhdl:119:13:@3ns:(report note): entry = 00000000000011011
bcd_mod_tb.vhdl:120:13:@3ns:(report note): outp = 000000000000000100111
bcd_mod_tb.vhdl:122:9:@3ns:(assertion note): End of test.

Функция to_string добавлена ​​для поддержки VHDL-совместимого инструмента.