【问题标题】:VHDL Shift right register issuesVHDL 右移寄存器问题
【发布时间】:2019-12-29 23:02:04
【问题描述】:

我是一个新手,我正在尝试在 VHDL 中实现一个除数组件的移位寄存器。移位寄存器必须采用 15 位输入并将其在每个时钟周期向右移位,同时在最高有效位上链接一个“0”。 我写了这段代码


------- 右移 ----------------------------------

>  library IEEE; use IEEE.STD_LOGIC_1164.ALL; use ieee.numeric_std.all;
> 
> entity shift_right is port(   in_shift_right: in std_logic_vector(14
> downto 0);
>       clk_shift_right, rst_shift_right : in std_logic;
>       out_shift_right : out std_logic_vector (14 downto 0) ); end shift_right;
> 
> architecture behavioral of shift_right is begin  
> process(clk_shift_right, rst_shift_right, in_shift_right )   variable
> tmp : std_logic_vector(14 downto 0);    begin
>     if rising_edge (clk_shift_right) then     elsif rst_shift_right = '1' then  
>       tmp := (others => '0');
>     elsif rising_edge(clk_shift_right) then 
>       tmp:='0'&in_shift_right(14 downto 1);
>           end if;
>            out_shift_right<=tmp;   end process;    end behavioral;

这是使用 Quartus 的图形工具测试的波形结果:

这不是我想要的,实际上只适用于第一个时钟周期。 虽然我在网上找到了以下代码

>      library IEEE;
>     use IEEE.STD_LOGIC_1164.ALL;
>     
>     entity shift is
>     port(
>           clk:in std_logic;
>           rst:in std_logic;
>           sin:in std_logic;
>           pin:in std_logic_vector(7 downto 0);
>           mode:in std_logic_vector(1 downto 0);
>           sout:out std_logic;
>           pout:out std_logic_vector(7 downto 0)
>           );
>     end shift;
>     
>     
>     architecture Behavioral of shift is
>     signal temp:std_logic_vector(7 downto 0);
>     
>     
>     begin
>         process(rst,clk,sin,mode,pin)
>           
>           begin
>           
>           if rst='1' then
>           sout<='0';
>           pout<="00000000";
>           temp<="00000000";
>           
>           
>           elsif(clk'event and clk='1')then
>           
>             case mode is
>             --SISO
>             when "00"=>
>             temp(6 downto 0)<= temp(7 downto 1);
>             temp(7)<=sin;
>             sout<=temp(0);
>             
>             --SIPO
>             when"01"=>
>             temp(6 downto 0)<= temp(7 downto 1);
>             temp(7)<=sin;
>             pout<=temp;
>           
>             --PIPO
>             when"10"=>
>             temp<=pin;
>             pout<=temp;
>            
>              
>             when others=>
>             null;
>             
>             end case;
>             
>           end if; 
>              
>           end process;
>           
>     end Behavioral;

它实际上可以按我的意愿工作,但是,正如您从波形中看到的那样,它仅在“案例”上选择的模式为“01”时才有效,但仅在“10”模式之后才有效。 我也无法理解为什么它仅在时钟周期延迟后才起作用,我在图片中突出显示:

非常感谢任何可以帮助我的人

【问题讨论】:

  • 你的代码很乱。我想如果你只是整理一下缩进,你会立即开始看到一些问题。

标签: vhdl shift


【解决方案1】:

如果你整理一下代码的缩进,我想你会立即开始看到一些问题。例如,想想这段代码会做什么:

if rising_edge (clk_shift_right) then

elsif rst_shift_right = '1' then  
    tmp := (others => '0');
elsif rising_edge(clk_shift_right) then
    ...

永远无法到达最终elsif 的内容。

第二条评论是您已将rstin_shift_right 放在敏感度列表中。您想要同步还是异步复位?如果是同步的,那么rst 不需要在敏感度列表中。不管怎样,我看不出有任何理由将in_shift_right 放在敏感度列表中。

第三条评论是,您对variable (tmp) 的使用可能令人担忧。您的用法完全有效且语法正确,但在这种情况下似乎是一个非常奇怪的选择。如果这是一个深思熟虑的风格选择,那很好。但是,如果您只是不了解 signalvariable 之间的区别,那么我建议您花一点时间来解决这个问题。请记住,这不是软件;你在描述硬件。

第四条评论是你的赋值tmp:='0'&amp;in_shift_right(14 downto 1);总是使用输入in_shift_right的高14位。这显然不是你想做的(你想继续向右移动)。试着想想需要什么样的硬件来做到这一点。

您已经包含了ieee.numeric_std 库,所以实际上有一个shift_right 函数可以直接使用。你没有准确描述你想让你的块做什么,但我想它是这样的(假设异步重置):

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

entity right_shifter is
generic (
    DATA_BITS       : positive := 15
);
port (
    clk             : in std_logic;
    rst             : in std_logic;
    -- Input
    in_valid        : in std_logic;
    in_data         : in std_logic_vector(DATA_BITS-1 downto 0);
    -- Control
    shift_enable    : in std_logic;
    -- Output
    out_data        : out std_logic_vector(DATA_BITS-1 downto 0)
);
end right_shifter;

architecture rtl of right_shifter is

    signal data     : unsigned(DATA_BITS-1 downto 0);

begin

    process(clk, rst)
    begin
        if rst = '1' then
            -- Reset
            data <= (others => '0');
        elsif rising_edge(clk) then
            if in_valid = '1' then
                -- Load new input
                data <= unsigned(in_data);
            elsif shift_enable = '1' then
                -- Shift right
                data <= shift_right(data, 1);
            end if;
        end if;
    end process;
    out_data <= std_logic_vector(data);

end rtl;

或者,使用同步重置:

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

entity right_shifter is
generic (
    DATA_BITS       : positive := 15
);
port (
    clk             : in std_logic;
    rst             : in std_logic;
    -- Input
    in_valid        : in std_logic;
    in_data         : in std_logic_vector(DATA_BITS-1 downto 0);
    -- Control
    shift_enable    : in std_logic;
    -- Output
    out_data        : out std_logic_vector(DATA_BITS-1 downto 0)
);
end right_shifter;

architecture rtl of right_shifter is

    signal data     : unsigned(DATA_BITS-1 downto 0);

begin

    process(clk)
    begin
        if rising_edge(clk) then
            if rst = '1' then
                -- Reset
                data <= (others => '0');
            elsif in_valid = '1' then
                -- Load new input
                data <= unsigned(in_data);
            elsif shift_enable = '1' then
                -- Shift right
                data <= shift_right(data, 1);
            end if;
        end if;
    end process;
    out_data <= std_logic_vector(data);

end rtl;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-02
    • 2013-01-09
    • 1970-01-01
    相关资源
    最近更新 更多