我想使用多路复用器为某些逻辑建模两个D触发器。当多路复用器选择DFF D1(B = 0)时,我希望三个MSB的静态输出为“000”,当多路复用器选择DFF D2(B = 1)时,三个LSB应固定为“111”。
这是我的代码 - 我最初在不检查明显语法错误的情况下盲目输入 - 下面。我不知道如何解决我的问题:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity dff_mux is
Port ( D1, D2 : in STD_LOGIC_VECTOR(11 DOWNTO 0);
clk : in STD_LOGIC;
rst : IN STD_LOGIC;
B : in STD_LOGIC;
data : out STD_LOGIC_VECTOR(11 DOWNTO 0));
end dff_mux;
architecture Behavioral of dff_mux is
signal Q1, Q2 : std_logic_vector(11 downto 0);
begin
process(clk,rst)
begin
if (rst = '1') then
Q1<="000000000000";
elsif (clk'event and clk='1') then
if (B = '0') then
-- I want to fix thee MSB to "000"
-- other bits shall retain their input value
D1(11) <= '0';
D1(10) <= '0';
D1(9) <= '0';
Q1 <= D1;
elsif (B = '1') then
-- fix three LSB to "111"
-- other bits retain their input value
D2(2) <= '1';
D2(1) <= '1';
D2(0) <= '1';
Q2 <= D2;
end if;
end if;
end process;
-- MUX description: select D1 when B = 0, else select D2 when B = 1
MUX : process(B)
begin
data <= Q1 when (B = '0') else
Q2;
end process MUX;
end Behavioral;
提前感谢任何可以帮助我的人。
答案 0 :(得分:1)
您的VHDL设计说明中存在许多错误。两个流程语句驱动相同的信号(Q1
和Q2
)。第二个进程有三个错误(没有进程语句标签,而标签是在关闭的并发信号赋值语句中指定的,其中顺序信号赋值语句是合适的)。看来第二个流程陈述应该全部消除。
如果要在Q1
,Q2
寄存器的输入上设置多路复用器,则第一个进程无法正常工作。您不能将值分配给块内的正式输入。
您应该直接在流程声明(B
Q1
内)将Q2
个选定值分配给clk
和elsif
。
您对D(11)的分配有缺陷(使用==
代替<=
)。
如果您只为特定信号分配一个值(例如,最长静态前缀D1
和D2
),则它不是多路复用器。请注意,提供的Q2
没有重置值。
没有分配地点数据。
如果你正在为课堂作业做这件事,那么在没有学习VHDL的情况下提供答案的人几乎没有什么好处。如果你正在努力学习VHDL,你需要更多并逐步建立练习。
如果我理解你正在尝试做什么,它会看起来像这样:
architecture Behavioral of basculeD is
-- signal Q1, Q2 : std_logic_vector(11 downto 0);
begin
-- process(clk,rst)
-- begin
-- if (rst='1') then Q1<="000000000000";
-- elsif ( clk'event and clk='1') then
-- if (B='0') then
-- D1(11) =='0'; -- i want to fix the 3MSB of D1 in the "000" ...
-- D1(10) <='0';
-- D1(9) <='0';
-- Q1<= D1;
-- elsif (B='1') then
-- D2(2)<= '1'; -- the 3LSB are fixed to 111 , and defaut value ...
-- D2(1)<='1';
-- D2(0)<='1';
-- Q2<=D2;
-- end if;
-- end if;
-- end process;
-- description MUX : select D1 when B=0, else select D2 when B= 1
-- process( B)
-- begin
-- Q1 <= D1 when B='0' else
-- Q2<=D2 when B='1' ;
-- end process MUX;
MUXED_REG:
process (clk,rst)
begin
if rst = '1' then
data <= (others => '0'); -- equivalent to "000000000000"
elsif clk'event and clk = '1' then
-- the actual multiplexer:
if B = '0' then
data <= ("000" & D1(8 downto 0));
else -- B = '1', or other values
data <= (D2(11 downto 3) & "111");
end if;
end if;
end process;
end Behavioral;
您当然可以保留一个中间信号,比如说Q
,并用它来代替上面的数据,同时将信号从Q
分配到data
(输出)。 / p>
使用上述架构代替您的分析。
使用测试台:
library ieee;
use ieee.std_logic_1164.all;
entity basculeD_test is
end entity;
architecture test of basculeD_test is
component basculeD is
port (
d1, d2: in std_logic_vector(11 downto 0);
clk: in std_logic;
rst: in std_logic;
b: in std_logic;
data: out std_logic_vector(11 downto 0)
);
end component;
signal d1: std_logic_vector(11 downto 0) := (others => '1');
signal d2: std_logic_vector(11 downto 0) := (others => '0');
signal clk: std_logic := '0';
signal rst: std_logic := '1';
signal b: std_logic := '0';
signal data: std_logic_vector(11 downto 0);
begin
CLOCK:
process
begin
wait for 10 ns;
clk <= not clk;
if Now > 100 ns then
wait;
end if;
end process;
RESET:
process
begin
wait for 31 ns;
rst <= '0';
wait;
end process;
DUT:
basculeD
port map (
d1 => d1,
d2 => d2,
clk => clk,
rst => rst,
b => b,
data => data
);
STIMULUS:
process
begin
wait for 65 ns;
b <= '1';
wait;
end process;
end architecture;
使用MUXED_REG
进程的basculeD替换架构:
david_koontz @ Macbook:ghdl -a basculeD.vhdl
david_koontz @ Macbook:ghdl -e basculeD_test
david_koontz @ Macbook:ghdl -r basculeD_test --wave = basculeD_test.ghw
david_koontz @ Macbook:open basculeD_test.gtkw(以前保存的保存文件)
给出:
当然有可能你试图将存储与多路复用完全分开,这表示你可以使用Q1
和Q2
作为寄存器(并且只需要9位),一个单独的多路复用器(如隐含在原始basculeD
architecture
)中,允许B
在输出Q1
上修改后的Q2
和data
寄存器值之间进行操控。
这看起来像这样:
architecture Behavioral of basculeD is
signal Q1: std_logic_vector(8 downto 0);
signal Q2: std_logic_vector(11 downto 3);
begin
REGS:
process (clk, rst)
begin
if rst = '1' then
Q1 <= (others => '0');
Q2 <= (others => '0');
elsif clk'event and clk = '1' then
Q1 <= D1 (8 downto 0);
Q2 <= D2(11 downto 3);
end if;
end process;
MUX:
process (B,Q1,Q2)
begin
if B = '0' then
data <= ("000" & Q1);
else
data <= (Q2 & "111");
end if;
end process;
并给你这样的东西:
VHDL旨在向读者传达设计规范,当使用某些约定来进行大写时(VHDL在扩展标识符中不区分大小写)和缩进时,它变得更容易。
答案 1 :(得分:0)
欢迎使用StackOverflow!首先,这是一个英文问题&amp;回答网站。请将所有相关术语翻译成英文,即basculeD =&gt; D触发器等。另外,尝试尽可能地描述您的问题,而不会有太多的拼写错误(拼写检查!)或语法错误。这将有助于其他人了解您并有效地帮助您。
无论如何,您的主要问题是,您有输入端口D1和D2,并尝试写入它们。相反,你应该只需要任何你需要的位,而忽略其他位。
不应该尝试写入输入,这是不可能的,你应该试试这个:
Q2 <= D2(11 downto 3) & "111";
该语句从D2获取位11到3,并将它们分配给Q2的第11位到第3位。 Q2的第2位到第0位被赋予常数值“111”。
您应该记住,您无法“重写”输入端口值。您的上一个流程也可以重写为并行语句。
此外,您的设计在某种意义上是独特的,您希望单独存储修改后的值。
考虑一下:
D1 = x“00A”; D2 = x“00B”,B ='0',clk - >上升趋势
现在,Q1 = x“00A”,Q2 = x“???”,数据= Q1 = x“00A”,B ='0',clk ='1'
现在,Q1 = x“00A”,Q2 = x“???”,数据= Q2 = x“???”,B ='1',clk ='1'
当你想在B ='1'和B ='0'之间切换时,你需要至少两个时钟周期来切换你的输出,因为Q1 resp Q2将保持旧的(可能是未初始化的)值。
您的设计可能无法完成您想要的操作。如果您需要多路复用器,请选择多路复用器。如果你想要一个触发器,建立一个触发器。
process(clk,rst)
begin
if (rst = '1') then
data <= (others => '0');
elsif (clk'event and clk='1') then
if (B = '1') then
-- Select D2
data <= D2(11 downto 3) & "111";
else
-- Select D1
data <= "000" & D1(8 downto 0);
end if;
end if;
end process;
您可能还想考虑重置是否真的合适以及同步重置是否更有益。