簡體   English   中英

VHDL:Std_Logic輸入以整數形式存儲

[英]VHDL: Std_Logic input stored in integer issue

我有以下問題:

我有一台PC,它為SPARTAN 3AN FPGA提供輸入,我希望獲取這些輸入,將其放入std_logic_vector中,然后將其轉換為整數。 指令分為“ n”條指令,每條32位。 我需要將前三個位放在一個整數中,將接下來的28個放在另一個整數中,最后一個是“最后一個指令標志”。 因此,我有兩個100個整數的數組,我將在其中放入指令(限制為100個)。 如果“最后指令標志”為1,則整個操作應停止。

該程序未正確合成,因此我對其進行了模擬。 我找到了問題,但是我不知道如何解決,所以我需要您的幫助。 這是代碼和模擬輸出:

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位沒有任何反應。 有什么想法嗎?

謝謝,博揚

模擬

第一個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);被覆蓋pre_int <= '0' & pre_int(31 downto 1); 因為(cnt<32) ,因此pre_int(31)尚不能變高。

當模擬更長的時間時,cnt會變為32,然后pre_int(31)會顯示一個'1'值。 se圖如下。

在此處輸入圖片說明

編輯:下面是帶有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;

波形圖如下所示。

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM