2013-09-26 2 views
0

У меня есть следующие проблемы:VHDL: std_logic вход хранится в целочисленном выпуске

У меня есть компьютер, который дает вклад в моей SPARTAN 3AN FPGA, и я хотел бы принести эти входы, положить их в std_logic_vector, а затем преобразовать их в целое число. Инструкции делятся на «n» инструкциями по 32 бита каждый. Мне нужно, чтобы первые три бита были помещены в одно целое, следующие 28 в другом, а последнее - «Последний флаг команды». Итак, у меня есть два массива из 100 целых чисел, в которые я бы поставил инструкции (100 - предел). Если «Последний флаг команды» равен единице, то вся операция должна прекратиться.

Программа не синтезировала правильно, поэтому я сделал ее симуляцию. И я нашел проблему, но я не знаю, как ее решить, поэтому мне нужна ваша помощь. Вот код и выход моделирования:

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
USE IEEE.NUMERIC_STD.all; 


entity BinaryDecimalConv is 
end BinaryDecimalConv; 

architecture Behavioral of BinaryDecimalConv is 

    type int_array is array (100 downto 0) of integer; 

    signal clkcnt: integer :=0; 
    signal fbaud: integer; 
    signal lastnumflag: std_logic:='0'; 
    signal clk: std_logic; 
    signal PLCinput: std_logic; 
    signal init: std_logic; 
    signal BusyIN: std_logic; 
    signal BusyOutSignal: std_logic; 
    signal InnerBusyOut: std_logic; 
    signal cnt: integer :=0; 
    signal fbaut: integer :=0; 
    signal pre_int: std_logic_vector (31 downto 0) := (others => '0'); 
    signal pre_spec_num: int_array := (others =>0); 
    signal cylinder: int_array := (others => 0); 
    signal InnerNumLength: integer:=0; 
    signal num_length: integer:=0; 

begin 

CLOCKK: Process is 
begin 
    clk<='0'; 
    wait for 10 ns; 
    clk<='1'; 
    wait for 10 ns; 
end process CLOCKK; 

fbaud <=5208; 
BusyIN <='0'; 
init <='0'; 

PLC: Process is 
    variable PrePLC: std_logic_vector(159 downto 0):="1010101010101010101010101001010010101010101010101010101010010100101010101010101010101010100101001010101010101010101010101001010010101010101010101010101010010101"; -- 1 with 100, 5 with 200, 5 2ith 200, 3 with 300, 4 with 750 
begin 
    PLCinput<=PrePLC(159); 
    PrePLC:= PrePLC(158 downto 1) & '0'; 
    wait for 104166 ns; 
end process;  


LastNum: process (LastNumFlag) is 
    begin 
    if LastNumFlag = '1' then 
     BusyOutSignal <='1'; 
     InnerBusyOut <='1'; 
    else 
     BusyOutSignal <='0'; 
     InnerBusyOut <='0'; 
    end if; 
    end process LastNum; 

DecoderAndAcquirer: process (PLCinput, BusyIN, InnerBusyOut,clk) is 
begin 

    if (clk'event and clk='1') then               -- If rising edge on clock 
     if ((BusyIN='0') and (InnerBusyOut='0') and (init='0')) then      -- Check if FPGA and PLC are ready to exchange information and if init is done 
      if (clkcnt = fbaud/2)     then         -- If clkcnt is equal to half of the duration of the input bit then 
       pre_int(31) <= PLCinput;             -- Initialize the last digit of pre_int 
       cnt <= cnt+1;                -- Incrementing cnt => going towards bit 2 
       clkcnt <=clkcnt+1;               -- Incrementing clkcnt so you can exit this block 
       if (cnt<32) then               -- Checking if not last bit 
        pre_int <= '0' & pre_int(31 downto 1);         -- If not last bit, shift number to right 
       else                  -- else 
        cnt <=0;                -- reset cnt to start with next instruction 
        if (pre_int(0)='1') then            -- Check if last digit is one 
         LastNumFlag <= '1';             -- If last digit is one, stop acquiring instructions 
        else 
         LastNumFlag <='0'; 
        end if; 
        pre_spec_num(InnerNumLength) <= to_integer(unsigned(pre_int(28 downto 1))); -- Conversion from binary to decimal for instruction 
        cylinder(InnerNumLength) <= to_integer(unsigned(pre_int(31 downto 29))); -- Conversion from binary to decimal for the number of cylinder 
        InnerNumLength <= InnerNumLength +1;           -- Incrementing the number of instructions 
        num_length <= InnerNumLength; 
       end if; 
      elsif (clkcnt = fbaud) then              -- If clkcnt has reached the entire length of the input bit 
       clkcnt <= 0;                -- set clkcnt to zero so the process can start from beginning. 
      else                   -- If clkcnt is less than or more than half of the entire duration, but surely 
       clkcnt <= clkcnt +1;              -- less than the entire duration, then increment the value of the clkcnt. 
      end if; 
     end if; 
    end if; 
end process DecoderAndAcquirer; 

end Behavioral; 

Дело в том, что, как показано на картинке, когда CNT изменения, ничего не происходит с 31-бит инструкции. Любые идеи почему?

Спасибо, Боян

Simulation

ответ

1

Первые PrePLC := PrePLC(158 downto 1) & '0'; несовпадения длины, поэтому я предполагаю, что это будет PrePLC := PrePLC(158 downto 0) & '0'; вместо этого, таким образом, работая в качестве регистра сдвига .

В процессе DecoderAndAcquirer коды есть:

... 
pre_int(31) <= PLCinput; 
... 
if (cnt<32) then 
    pre_int <= '0' & pre_int(31 downto 1); 
... 

Так что даже через pre_int(31) назначено, он впоследствии переписан в pre_int <= '0' & pre_int(31 downto 1); так (cnt<32), в результате чего pre_int (31) наклоняет высокоуровневый еще.

При моделировании более длительного времени cnt переходит на 32, а затем значение «1» отображается в pre_int (31); ниже.

enter image description here

Отредактировано: Ниже вариант с временной переменной для pre_int, просто чтобы показать принципы; операция не проверяется.

DecoderAndAcquirer: process (PLCinput, BusyIN, InnerBusyOut,clk) is 
    variable pre_int_v : std_logic_vector(pre_int'range); 
begin 

    if (clk'event and clk='1') then               -- If rising edge on clock 
     pre_int_v := pre_int; -- Variable update from signal 
     if ((BusyIN='0') and (InnerBusyOut='0') and (init='0')) then      -- Check if FPGA and PLC are ready to exchange information and if init is done 
      if (clkcnt = fbaud/2)     then         -- If clkcnt is equal to half of the duration of the input bit then 
       pre_int_v(31) := PLCinput;             -- Initialize the last digit of pre_int 
       cnt <= cnt+1;                -- Incrementing cnt => going towards bit 2 
       clkcnt <=clkcnt+1;               -- Incrementing clkcnt so you can exit this block 
       if (cnt<32) then               -- Checking if not last bit 
        pre_int_v := '0' & pre_int_v(31 downto 1);         -- If not last bit, shift number to right 
       else                  -- else 
        cnt <=0;                -- reset cnt to start with next instruction 
        if (pre_int_v(0)='1') then            -- Check if last digit is one 
         LastNumFlag <= '1';             -- If last digit is one, stop acquiring instructions 
        else 
         LastNumFlag <='0'; 
        end if; 
        pre_spec_num(InnerNumLength) <= to_integer(unsigned(pre_int_v(28 downto 1))); -- Conversion from binary to decimal for instruction 
        cylinder(InnerNumLength) <= to_integer(unsigned(pre_int_v(31 downto 29))); -- Conversion from binary to decimal for the number of cylinder 
        InnerNumLength <= InnerNumLength +1;           -- Incrementing the number of instructions 
        num_length <= InnerNumLength; 
       end if; 
      elsif (clkcnt = fbaud) then              -- If clkcnt has reached the entire length of the input bit 
       clkcnt <= 0;                -- set clkcnt to zero so the process can start from beginning. 
      else                   -- If clkcnt is less than or more than half of the entire duration, but surely 
       clkcnt <= clkcnt +1;              -- less than the entire duration, then increment the value of the clkcnt. 
      end if; 
     end if; 
     pre_int <= pre_int_v; -- Signals update from variable 
    end if; 
end process DecoderAndAcquirer; 

Рисунок с формой волны показан ниже.

enter image description here

+0

Да, для первого, вы правы. Я пропустил один бит (как он его имитирует?). Для второго: я хочу перезаписать его. Поскольку PLCinputs будет поступать каждые 104166 нс, и я хочу, чтобы они были сдвинуты вправо, поэтому, даже если он не показывает его значение в тот момент, когда он приобретает значение, он должен показывать preint (30) как 1, потому что я на самом деле сделал pre_int (30) <= pre_int (31), когда я переместил его вправо. Предположим, что это первая итерация, и у меня есть 00000000000000000000000000000000, тогда, когда PLCinput прибывает, она становится 10000000000000000000000000000000. –

+0

Когда я использую pre_int <= '0' и pre_int (31 до 1), я обрезал один ноль с конца, сделав его 10000000000000000000000000000000000, и добавление нуля спереди, делая его 01000000000000000000000000000000. Таким образом, это должно появиться на графике. Не так ли? –

+1

Для первого: ModelSim сообщает об ошибке из-за несоответствия длины, поэтому звучит так, как ваш симулятор не достаточно разборчив.Для второго: я добавил цифру, которая показывает pre_int (31) как «1» после более длительного моделирования, поэтому cnt получает 32. Для вашего последнего комментария: Нет, первый 'pre_int (31) <= PLCinput;' не имеет любой эффект, так как присвоение сигнала '<=' не изменяет значение сигнала перед следующим циклом моделирования, поэтому последующее 'pre_int <= '0' и pre_int (31 downto 1)' будет использовать текущее значение pre_int, в результате чего все 0. –

Смежные вопросы