首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >VHDL微处理器/微控制器

VHDL微处理器/微控制器
EN

Stack Overflow用户
提问于 2014-01-06 17:39:33
回答 1查看 4K关注 0票数 1

我正在学习Xilinx (VHDL)上的代码。接下来,我想做一个简单的微处理器/微控制器,并在此过程中学习一些关于片组件的知识。因此,我的目标是尝试编码一个8位微处理器使用AMD 2901 (4位片)。(我已经掌握了2901的代码及其输入和输出信号的所有信息。)

我知道第一步将是建立微处理器的体系结构,所以我最终得到了这样的结果(我知道总线的带宽与我想要的非常不同)。

http://www.cs.binghamton.edu/~reckert/wk15fig1.JPG (基本上我对微处理器和微控制器的了解都是从这里得到的,http://www.cs.binghamton.edu/~reckert/hardwire3new.html)

以下是关于准时的问题:

  1. 如何编写如图所示的中央总线代码?如何使用像图表这样的中央总线来“听”和“写”我的内存和组件?
  2. 我想使用2901 ALU (其中两个),所以我有一个8位微处理器.问题是:假设我的操作码使用xxxxx001 (其中x是控制信号,001表示添加ALU)对ALU添加函数,所以.由于我有一个切片ALU,我的操作码应该是xxxxx001001,以便给两个ALU提供指令?或者ALU应该共享相同的"001“命令?(我想,知道如何使用VHDL中的总线,让两个端口“监听”或其他什么的,这是可以做到的。)
  3. 如果你能与我分享一些教程或信息链接,可以帮助我实现我的目标,这将是令人敬畏的。我搜索了很多,发现的信息非常少。
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-06 23:41:48

这个答案是关于你问题的第三部分。

您可能会发现看一看MCPU项目是有用的。它是一个8位CPU,有77行VHDL代码.因为作者已经将整个设计压缩成32个宏单元,所以在某些地方,代码有点棘手,但是设计文件提供了帮助。

我还创建了一个旨在提高代码可读性的重构版本,如下所示。请注意,我不是这个项目的最初作者--所有的荣誉都属于Tim scke。

代码语言:javascript
复制
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity mcpu is
    port (
        data_bus: inout std_logic_vector(7 downto 0);
        address: out std_logic_vector(5 downto 0);
        n_oe: out std_logic;
        -- Asynchronous memory interface
        n_we: out std_logic;    
        n_reset: in std_logic;
        clock: in std_logic
    );
end;

architecture refactored of mcpu is
  signal accumulator: std_logic_vector(8 downto 0);
  alias carry is accumulator(8);  
  alias result is accumulator(7 downto 0);
  alias opcode is data_bus(7 downto 6);

  signal address_register: std_logic_vector(5 downto 0);
  signal pc: std_logic_vector(5 downto 0);
  signal states: std_logic_vector(2 downto 0);

  type cpu_state_type is (FETCH, WRITE, ALU_ADD, ALU_NOR, BRANCH_NOT_TAKEN);
  signal cpu_state: cpu_state_type;

  type state_encoding_type is array (cpu_state_type) of std_logic_vector(2 downto 0);
  constant STATE_ENCODING: state_encoding_type := (
      FETCH => "000", 
      WRITE => "001", 
      ALU_ADD => "010", 
      ALU_NOR => "011", 
      BRANCH_NOT_TAKEN => "101"
  );

begin
    process (clock, n_reset)
    begin
        if not n_reset then
            -- start execution at memory location 0
            address_register <= (others => '0');  
            states <= "000";
            cpu_state <= FETCH;
            accumulator <= (others => '0');
            pc <= (others => '0');
        elsif rising_edge(clock) then

            -- PC / Adress path
            if cpu_state = FETCH then
              pc <= address_register + 1;
              address_register <= data_bus(5 downto 0);
            else
              address_register <= pc;
            end if;

            -- ALU / Data Path
            case cpu_state is
                when ALU_ADD => 
                    accumulator <= ('0' & result) + ('0' & data_bus);
                when ALU_NOR => 
                    result <= result nor data_bus;
                when BRANCH_NOT_TAKEN => 
                    carry <= '0';
                when others => null;
            end case;

            -- State machine
            if cpu_state /= FETCH then 
                cpu_state <= FETCH;
            elsif opcode ?= "11" and carry then 
                cpu_state <= BRANCH_NOT_TAKEN;
            else
                states <= "0" & not opcode;       -- execute instruction
                case opcode is
                    when "00" => cpu_state <= ALU_NOR;  -- 011
                    when "01" => cpu_state <= ALU_ADD;  -- 010                    
                    when "10" => cpu_state <= WRITE;    -- 001
                    when "11" => cpu_state <= FETCH;    -- 000
                    when others => null;                     
                end case;
            end if;
        end if;
    end process;

    -- output
    address <= address_register;    
    data_bus <= result when (cpu_state = WRITE) else (others => 'Z');

    -- output enable is active low, asserted only when
    -- rst=1, clk=0, and state!=001(wr_acc) and state!=101(read_pc)
    n_oe <= '1' when (clock='1' or cpu_state = WRITE or n_reset = '0' or cpu_state = BRANCH_NOT_TAKEN) else '0';

    -- write enable is active low, asserted only when
    -- rst=1, clk=0, and state=001(wr_acc)
    n_we <= '1' when (clock = '1' or cpu_state /= WRITE or n_reset = '0') else '0';

end;
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20955863

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档