【问题标题】:Implementing a 10 bit shift register with led outputs使用 LED 输出实现 10 位移位寄存器
【发布时间】:2017-03-24 19:43:47
【问题描述】:

我正在尝试实现以下移位寄存器

entity MyShiftRegister is
    port(
        clock:   in  std_logic;
        DataIn:  in  std_logic_vector (9 downto 0); 
        Left:    in  std_logic;  --synchronous left rotate
        Right:   in  std_logic;  --synchronous right rotate
        Load:    in  std_logic;  --synchronous parallel load
        Clear:   in  std_logic;  -- synchronous clear
        DataOut: out std_logic_vector (9 downto 0);     

这是我目前所拥有的


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

entity question2 is
    Port (
        led: buffer std_logic_vector (9 downto 0);
        clk: in std_logic;
        btnu: in std_logic;
        btnL: in std_logic;
        btnR: in std_logic ; 
        btnD: in std_logic;
        btnC: in std_logic 
     );
end question2;

architecture Behavioral of question2 is
    constant active: std_logic :='1';
    constant inactive: std_logic :='0';

    constant step_zero:  std_logic_vector(9 downto 0) :="0000000000";  
    constant step_one:   std_logic_vector(9 downto 0) :="0000000001";
    constant step_two:   std_logic_vector(9 downto 0) :="0000000010"; 
    constant step_three: std_logic_vector(9 downto 0) :="0000000100";
    constant step_four:  std_logic_vector(9 downto 0) :="0000001000";
    constant step_five:  std_logic_vector(9 downto 0) :="0000010000";
    constant step_six:   std_logic_vector(9 downto 0) :="0000100000";    
    constant step_seven: std_logic_vector(9 downto 0) :="0001000000";
    constant step_eight: std_logic_vector(9 downto 0) :="0010000000";
    constant step_nine:  std_logic_vector(9 downto 0) :="0100000000";
    constant step_ten:   std_logic_vector(9 downto 0) :="0100000000";

    signal DataIn: std_logic_vector (9 downto 0):= "1111111111";  
    signal Load: std_logic := btnD;
    signal Reset: std_logic; 
    signal Left: std_logic:= btnL;
    signal Right: std_logic:= btnR;
    signal DataOut: std_logic_vector := led (9 downto 0);
    signal Clear: std_logic:= btnU;
    signal speed_enable: std_logic; 
begin
    SpeedControl: process (clk)
        variable counter: integer range 0 to 10000000;
    begin
        speed_enable<=not active;  
        if Reset = Active then
            counter:= 0; 
        elsif (rising_edge (clk)) then 
            counter := counter + 1; 
            if (counter=10000000) then 
                speed_enable<= Active; 
                counter:=0; 
            end if; 
        end if; 
    end process; 

    shiftregister: process(clk, clear)
    begin
        if rising_edge (clk) then 
            if clear= active then 
                DataOut <= (others => '0');  
            elsif load = active then 
                DataOut <= DataIn ; 
            elsif Left = active then 
                DataOut <= DataOut(8 downto 0) & "1" ;
                if DataOut = "1000000000" then 
                    clear <= active;   
                elsif Right = active then 
                    DataOut <= DataOut (9 downto 1) & "1" ;
                    if DataOut = "0000000001" then 
                        clear <= active; 
                    end if; 
                end if; 
            end if; 
        end if;  
end process;

with DataOut select
    led <= step_one   when "0000",
           step_two   when "0001",
           step_three when "0010",
           step_four  when "0011",
           step_five  when "0100",
           step_six   when "0101",
           step_seven when "0110",
           step_eight when "0111",
           step_nine  when "1000", 
           step_ten   when "1001", 
           step_zero  when others;     
end Behavioral;

我如何准确地左右旋转位并将其绑定到我的 LED 输出。我正在考虑使用计数器,并且只是递增和递减以向左或向右移位,但我不确定这是否仍被视为移位寄存器。

谢谢

【问题讨论】:

  • 这段代码充满了设计错误,毫无意义。为什么要使用 led 的多路复用器? DataOut 不是 4 位;这是一个语法错误。您的左移和右移分支无法正确移动或旋转(尤其是右移)。您的实际实体与您提供的作为您尝试实施的实体不匹配。速度控制过程无法综合,因为它混合了组合和注册分配。默认值 (:=) 不是默认连接。您了解同步桶形移位器(由MyShiftRegister 实体描述)应该做什么吗?
  • 您列出的所有其他问题我仍在编写代码。我只是不明白如何在不使用计数器移动位的情况下左移或右移
  • DataOut &lt;= DataOut(8 downto 0) &amp; DataOut(9) ; 向左旋转,DataOut &lt;= DataOut(8 downto 0) &amp; "0" ; 向左移动,DataOut &lt;= DataOut(0) &amp; DataOut(9 downto 1); 向右旋转,DataOut &lt;= "0" &amp; DataOut(9 downto 1); 向右移动。自动清除是不必要的,实际上破坏了预期的功能。
  • 通常,桶形移位器在左或右输入上的每个脉冲将位向左或向右旋转一个位置。您使用DataOut 作为您的存储元素,尽管它可能应该是一个不同名称的信号。可以将存储元素复制到您的输出端口,例如led &lt;= DataOut(在并发空间中,而不是在您的时钟进程中)。
  • 如果我有活跃的高 LED。因此,为了让 LED 旋转,我是否需要声明我的任何 DataOut 位最初为高

标签: vhdl shift-register


【解决方案1】:

开始:

constant step_nine:  std_logic_vector(9 downto 0) :="0100000000";
constant step_ten:   std_logic_vector(9 downto 0) :="0100000000";

不正确。应该是

constant step_nine:  std_logic_vector(9 downto 0) :="0100000000";
constant step_ten:   std_logic_vector(9 downto 0) :="1000000000";

但无论如何,这种方法很容易出错。让我们简化一下:

process(sel)
    variable selected_led : natural;
begin
    led <= (others => '0');
    selected_led := to_integer(unsigned(sel));
    if selected_led < led'length then
        led(selected_led) <= '1';
    end if;
end process;

如果led(selected_led) &lt;= '1'; 无法合成,您可能需要将其更改为

for i in 0 to led'length-1 loop
    if (i = selected_led) then
        led(i) <= '1';
    end if;
end loop;

至于使用buffer 端口。不。最好只使用inout。如果您想读取out 端口,请使用 VHDL-2008 进行编译,或者在两者之间使用临时信号。

然后注意rightleft是VHDL中的关键字。你不应该使用它们

您想要的是非常简单和基本的 VHDL。示例(使用 VHDL-2008):

process(clock)
begin
    if rising'edge(clock) then
        if clear = '1' then
            data_out <= (others => '0');
        elsif load = '1' then
            data_out <= data_in;
        elsif right_rotate = '1' then
            data_out <= data_out(0) & data_out(data_out'length-1 downto 1);
        elsif left_rotate = '1' then
            data_out <= data_out(data_out'length-2 downto 0) &
                data_out(data_out'length-1);
        end if;
    end if;
end process;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多