如何在VHDL中从实体变量创建子信号/子变量?

时间:2018-04-07 17:00:56

标签: vhdl

我目前正在用VHDL实现MIPS处理器。系统组件(将ALU,寄存器文件,控制单元等粘合在一起)具有以下实体描述:

entity system is
    port (
                 reset : in std_logic;
                 sys_clk : in std_logic;
                 instruction : in std_logic_vector(15 downto 0);
                 sys_mem_dump : in std_logic := '0'
         );
end system;

在本系统的体系结构部分,我试图创建指令变量的“子变量”,对应于正在使用的操作码和寄存器。

architecture Behavioral of system is
        instruction_opcode : std_logic_vector(3 downto 0) := instruction(15 downto 12);
        instruction_rd : std_logic_vector(3 downto 0) := instruction(11 downto 8); -- destination register
        instruction_rs : std_logic_vector(3 downto 0) := instruction(7 downto 4); -- source register
        instruction_rt : std_logic_vector(3 downto 0) := instruction(3 downto 0); -- target register
        -- a bunch of signals
begin 
    -- a bunch of port maps
end Behavioral

我已经尝试了signalvariableshared_variableconstant,但这些导致我在端口映射其中一个时未初始化寄存器文件的地址它的变量。我也尝试将这些变量放在系统实体端口中,但这也不起作用。我不想将系统实体端口中的instruction变量拆分为这四个变量。

2 个答案:

答案 0 :(得分:2)

同意paebles:你似乎缺乏基本的VHDL知识,应该在你的书中寻找。

你至少应该知道这个方法:

touchesMoved

但实际上您可以使用别名:

class ViewController: UIViewController {

    var gr: UIPinchGestureRecognizer!

    override func viewDidLoad() {
        super.viewDidLoad()
        gr = UIPinchGestureRecognizer(target: self, action: #selector(pinched(_:)))
        gr.delaysTouchesBegan = true
        view.addGestureRecognizer(gr)
    }

    @IBAction func buttonTapped(_ sender: Any) {
        gr.isEnabled = !gr.isEnabled
        print("pinch recognizer enabled: \(gr.isEnabled)")
    }

    @objc func pinched(_ gr: Any?) {
        print("pinched")
    }

    var i = 0

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        i = 0
        print("touchesBegan")
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("touchesMoved \(i)")
        i += 1
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("touchesEnded")
    }

    override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("touchesCancelled")
    }
}

答案 1 :(得分:1)

反映您的评论的共同主题

  

@Paebbels是否根本无法在VHDL中执行此操作?我查看了synario手册和其他一些网站,没有一个数据对象类型符合这个用例。

您使用的参考资料不足。

除了JH Bonarius&#39;中描述的中间信号和对象别名之外。回答有一种方法使用声明为子类型的索引范围:

library ieee;
use ieee.std_logic_1164.all;

entity field is
    port (
        fourbitfield:   in  std_logic_vector (3 downto 0)
    );
end entity;

architecture foo of field is 
begin
end architecture;

library ieee;
use ieee.std_logic_1164.all;

entity system is
    port (
        reset:          in  std_logic;
        sys_clk:        in  std_logic;
        instruction:    in  std_logic_vector(15 downto 0);
        sys_mem_dump:   in  std_logic := '0'
    );
end entity system;

architecture foo of system is
    subtype opcode is integer range 15 downto 12;
    subtype rd is integer range 11 downto 8;
    subtype rs is integer range 7 downto 4;
    subtype rt is integer range 3 downto 0;
begin
U1: 
    entity work.field port map (instruction(opcode));

U2: 
    entity work.field port map (instruction(rd));

U3: 
    entity work.field port map (instruction(rs));

U4: 
    entity work.field port map (instruction(rt));
end architecture;

这分析,阐述和模拟(在证明缺少边界错误时实际上没有做任何事情)。

实体是一个独立的设计单元,自然允许抽象(端口名称在组件实例化过程中与端口映射中的实际信号相关联)。所有其他形式的名称或使用中间对象都是旨在提高可读性的抽象形式,并且由风格决定。

在上面的instruction(opcode)中,它们是以整数子类型的形式提供离散范围的切片名称(IEEE Std 1076-2008 8.5切片名称)。您也可以直接使用具有离散范围(例如15 downto 12)的切片名称作为关联列表中的实际值而不声明子类型:

U1:
    entity work.field port map (fourbitfield => instruction(15 downto 12));

在此处显示的正式端口和实际信号之间使用命名关联可以排除进一步抽象的需要。口述抽象会影响VHDL标准不需要的样式。

您对子信号或变量的想法与VHDL中的切片名称一致,就像使用中间信号一样容易。别名只是命名实体的其他名称(包括对象切片)。

如果你使用哪种额外的抽象方法可能取决于预期读者的复杂程度。

如果有人要彻底搜索Stackoverflow上的标记,您可以找到所有这三种方法的示例。诡计读者可以编辑您的问题以符合VHDL语法并将其作为副本提交。