VHDL实现主从D触发器报错:无法写入IN模式接口D的解决方法
解决VHDL主从D触发器的端口赋值错误与Altera D2引脚分配问题
错误原因分析
你遇到的"无法写入IN模式的接口对象'D'"错误,核心问题是VHDL的输入端口(IN模式)不能在模块内部被赋值。你的代码里写了D<=SW(0);,但如果D是被定义为IN类型的端口,模块内部只能读取它的值,不能给它赋值——SW(0)应该作为外部输入连接到D端口,而不是反过来在结构体里给D赋值。
正确的主从D触发器实现步骤
1. 完整的VHDL代码(包含实体与结构体)
首先要明确顶层模块的端口定义,把SW(0)、SW(1)作为顶层的输入,LEDR作为输出,然后在结构体里实例化门电路和锁存器:
library IEEE; use IEEE.STD_LOGIC_1164.ALL; -- 顶层模块实体定义 entity MasterSlaveDFF is Port ( SW : in STD_LOGIC_VECTOR(1 downto 0); -- SW(0)=D输入, SW(1)=Clk输入 LEDR : out STD_LOGIC_VECTOR(2 downto 0) -- LEDR(0)=D, LEDR(1)=Clk, LEDR(2)=Q输出 ); end MasterSlaveDFF; architecture Structural of MasterSlaveDFF is -- 声明子模块:非门 component notGate Port ( input : in STD_LOGIC; output : out STD_LOGIC ); end component; -- 声明子模块:门控D锁存器 component gdlatch Port ( En : in STD_LOGIC; D : in STD_LOGIC; Q : out STD_LOGIC; Qn : out STD_LOGIC ); end component; -- 内部信号声明 signal invOut1, invOut2 : STD_LOGIC; signal Dout : STD_LOGIC; signal Q, notQ : STD_LOGIC; begin -- 把SW的输入映射到输出显示(读取输入而非赋值给IN端口) LEDR(0) <= SW(0); -- 显示D输入状态 LEDR(1) <= SW(1); -- 显示Clk输入状态 LEDR(2) <= Q; -- 显示触发器最终输出Q -- 实例化非门,生成CLK的反相信号 G1: notGate port map(input => SW(1), output => invOut1); G2: notGate port map(input => invOut1, output => invOut2); -- 实例化主锁存器(由~CLK控制) G3: gdlatch port map(En => invOut1, D => SW(0), Q => Dout, Qn => open); -- 实例化从锁存器(由CLK控制) G4: gdlatch port map(En => invOut2, D => Dout, Q => Q, Qn => notQ); end Structural;
2. 关键修正点
- 顶层模块的
SW作为输入端口,直接读取SW(0)作为D输入、SW(1)作为Clk输入,彻底避免了给IN端口赋值的错误。 - 子模块实例化时,直接用
SW(0)作为gdlatch的D输入,无需额外定义中间D端口。 - 移除了错误的
D<=SW(0);和Clk<=SW(1);赋值语句,改为直接将输入信号映射到显示LED或子模块端口。
Altera D2开发板的引脚分配
要把SW(0)、SW(1)和LEDR(0-2)绑定到硬件引脚,有两种便捷方式:
方式1:Quartus Prime图形化分配
- 打开Quartus Prime,进入
Assignment > Assignment Editor。 - 在
Category栏选择Locations。 - 左侧
To列选择对应信号:SW[0]、SW[1]、LEDR[0]、LEDR[1]、LEDR[2]。 - 右侧
Location栏输入D2开发板的实际引脚号(比如SW0对应PIN_AA13,SW1对应PIN_Y13,LEDR0对应PIN_AB12,具体以开发板手册为准)。
方式2:代码内添加引脚约束
直接在实体声明后添加attribute location属性,示例如下:
entity MasterSlaveDFF is Port ( SW : in STD_LOGIC_VECTOR(1 downto 0); LEDR : out STD_LOGIC_VECTOR(2 downto 0) ); -- 替换为D2开发板实际引脚号 attribute location : string; attribute location of SW(0) : signal is "AA13"; attribute location of SW(1) : signal is "Y13"; attribute location of LEDR(0) : signal is "AB12"; attribute location of LEDR(1) : signal is "AC12"; attribute location of LEDR(2) : signal is "AD12"; end MasterSlaveDFF;
额外注意事项
- 确保
notGate和gdlatch子模块的逻辑正确,比如gdlatch需满足:当En为高时锁存D输入,低电平时保持当前状态。 - 编译前确认所有子模块都已添加到项目中,避免编译报错。
内容的提问来源于stack exchange,提问作者George Nemoukos




