У меня есть следующие проблемы: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-бит инструкции. Любые идеи почему?
Спасибо, Боян
Да, для первого, вы правы. Я пропустил один бит (как он его имитирует?). Для второго: я хочу перезаписать его. Поскольку PLCinputs будет поступать каждые 104166 нс, и я хочу, чтобы они были сдвинуты вправо, поэтому, даже если он не показывает его значение в тот момент, когда он приобретает значение, он должен показывать preint (30) как 1, потому что я на самом деле сделал pre_int (30) <= pre_int (31), когда я переместил его вправо. Предположим, что это первая итерация, и у меня есть 00000000000000000000000000000000, тогда, когда PLCinput прибывает, она становится 10000000000000000000000000000000. –
Когда я использую pre_int <= '0' и pre_int (31 до 1), я обрезал один ноль с конца, сделав его 10000000000000000000000000000000000, и добавление нуля спереди, делая его 01000000000000000000000000000000. Таким образом, это должно появиться на графике. Не так ли? –
Для первого: ModelSim сообщает об ошибке из-за несоответствия длины, поэтому звучит так, как ваш симулятор не достаточно разборчив.Для второго: я добавил цифру, которая показывает pre_int (31) как «1» после более длительного моделирования, поэтому cnt получает 32. Для вашего последнего комментария: Нет, первый 'pre_int (31) <= PLCinput;' не имеет любой эффект, так как присвоение сигнала '<=' не изменяет значение сигнала перед следующим циклом моделирования, поэтому последующее 'pre_int <= '0' и pre_int (31 downto 1)' будет использовать текущее значение pre_int, в результате чего все 0. –