本人所写的博客都为开发之中遇到问题记录的随笔,主要是给自己积累些问题。免日后无印象,如有不当之处敬请指正(欢迎进扣群 24849632 探讨问题);

要在不改变NES文件的情况下运行游戏程序,那么需要有一颗可以运行此机器码的CPU,因此我打算从开始重构一颗2A03CPU开始。经过这两天的工作,现在CPU的框架已经完成。

这个版本并没有按8位机的规范进行时序流程的设计,16位地址的计算直接使用两个加法单元,期待在一个时钟周期内,便将6502的绝对地址间接寻址功能完成了地址进行计算、内存取数、间接计算、甚至数据回存都完成。但因为时序逻辑比较混乱,QUARTS II 在生成网表时将所有的逻辑门都优化成了0,因此为了更快的解决问题,因此这一版本的架构直接做废。

第二版本重新对CPU的架构进行了优化,完全按8位机的架构进行设计,以下便将完成框架图中的各个组件,并完成子模块的仿真及设计。

编写PC及最简控制器

stack.vhdl

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL; entity stack is generic (SIZE:INTEGER := 128); port(wr        :  IN    std_logic; cs        :  IN    std_logic; clk       :  IN    std_logic; reset     :  IN    std_logic; addr      :  INOUT std_logic_vector(15 downto 0) );
end stack; architecture arch_stack of stack is
type stack_ARRAY is array (0 to SIZE-1) of std_logic_vector (15 downto 0);
signal stack_body : stack_ARRAY;
signal stack_postion : integer range 0 to 127;
begin process(clk,reset) begin if(reset='1') then stack_postion <= 0; elsif(rising_edge(clk)) then if(cs='1') then if(wr='1') then --pop addr <= stack_body(stack_postion); stack_postion <= stack_postion-1; else stack_body(stack_postion) <= addr; stack_postion <= stack_postion+1; end if; end if; end if; end process;
end arch_stack; -- configuration config_stack of stack is
--     for arch_stack
--     end for;
-- end configuration; 

rom.vhdl

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE WORK.PRJCONFIG.ALL;entity rom is generic (SIZE:INTEGER := 256); port(clk       :  IN    std_logic; wr        :  IN    std_logic; addr      :  IN    std_logic_vector(15 downto 0); data      :  IN    std_logic_vector(7 downto 0); code      :  OUT   std_logic_vector(7 downto 0) );
end rom; architecture arch_rom of rom is
type rom_ARRAY is array (SIZE-1 downto 0) of std_logic_vector (7 downto 0);
signal rom_body : rom_ARRAY;
begin process(clk) variable addr_temp: BYTE; begin if(rising_edge(clk)) then if(addr(15)='1') then -- address limit at 8000H ~ FFFFH addr_temp := conv_integer(addr); if(wr='1') then rom_body(addr_temp) <= data; else code <= rom_body(addr_temp); end if; end if; end if; end process;
end arch_rom; -- configuration config_rom of rom is
--     for arch_rom
--     end for;
-- end configuration; 

pc.vhdl

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
-- USE IEEE.NUMERIC_STD.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE WORK.PRJCONFIG.ALL;entity pc is port (-- input from global clk        : in  std_logic; -- input form nesupdatareset      : in  std_logic; -- input form controller ent        : in  std_logic; load       : in  std_logic; model      : in  std_logic_vector(1 downto 0); preset     : in  std_logic_vector(15 downto 0); -- io to statck saddr      : inout std_logic_vector(15 downto 0); -- output to rom pcout      : out   std_logic_vector(15 downto 0) );
end pc; architecture arch_pc of pc is
signal current_pc: WORD := 0;
beginprocess(clk,reset,load,model) begin -- clock process if(reset='1') then -- 【复位信号】为高时清除PC值,回程序起始位置 current_pc <= 0; elsif(rising_edge(clk)) then if(model(1)='1') then -- 【栈地址】保存与恢复 if(load='1') then -- from stack to pc current_pc <= CONV_INTEGER(saddr); else -- from pc to stack saddr <= CONV_STD_LOGIC_VECTOR(current_pc,16); end if; elsif(model(0)='1') then if(load='1') then -- 从地址预设线中加载地址数据 current_pc <= CONV_INTEGER(preset); elsif(ent='1') then -- 指向下一指令地址 current_pc <= current_pc+1; end if; saddr <= (others=>'Z'); end if; pcout <= CONV_STD_LOGIC_VECTOR(current_pc,16); end if; end process;
end arch_pc;

nesupdata.vhdl

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE WORK.PRJCONFIG.ALL;entity nesupdata is port(-- from global clk       :  IN  std_logic;reset_n   :  IN  std_logic;-- avalon jock  avalon_wr  :  IN  std_logic; avalon_addr:  IN  std_logic_vector(2 downto 0); avalon_data:  IN  std_logic_vector(24 downto 0); -- output to rom rom_wr    :  OUT  std_logic; rom_addr  :  OUT  std_logic_vector(15 downto 0); rom_data  :  OUT  std_logic_vector(7 downto 0); -- output to pc sys_reset :  OUT  std_logic; -- output to control ctr_pause :  OUT  std_logic );
end nesupdata; architecture arch_nesupdata of nesupdata is
begin process(clk,reset_n) begin if(reset_n='0') then sys_reset <= '1'; ctr_pause <= '1'; elsif(rising_edge(clk)) then sys_reset <= '0'; if(avalon_wr='0') then case avalon_addr is when "000" => -- nes 数据下载或停止命令 if(avalon_data(0)='1') then rom_wr <= '1'; ctr_pause <= '1'; sys_reset <= '1'; else rom_wr <= '0'; end if; when "001" => -- 下载NES调色板数据 rom_addr <= avalon_data(23 downto 8); rom_data <= avalon_data(7 downto 0); when "010" => -- 下载NES游戏数据 rom_addr <= avalon_data(23 downto 8); rom_data <= avalon_data(7 downto 0); when "011" => -- NES游戏开始 rom_wr <= '0'; ctr_pause <= '0'; sys_reset <= '0'; when others => null; end case; end if; end if; end process;
end arch_nesupdata; 

controller.vhdl

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
-- USE IEEE.NUMERIC_STD.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE WORK.PRJCONFIG.ALL;entity controller is port (-- input from global clk        : in    std_logic; -- nesupdate to controller reset      : in    std_logic; pause      : in    std_logic; -- controller to pc ent        : out   std_logic; load       : out   std_logic; abs_addr   : out   std_logic_vector(15 downto 0); -- rom to controller rom_code   : in    std_logic_vector(7 downto 0); -- memory & controller op_cmd     : out   std_logic_vector(15 downto 0); mem_addr   : out   std_logic_vector(15 downto 0); mem_data   : inout std_logic_vector(7 downto 0); -- register status     : inout std_logic_vector(7 downto 0) );
end controller; architecture arch_controller of controller is
signal cmd_type: INDTYPE;
signal acc_temp,x_temp,y_temp: std_logic_vector(7 downto 0);
signal future_state, current_state: PRCSTATU;
beginprocess(clk,reset,pause) begin if(reset='1') then future_state <= PRCSTATU_READY;elsif(rising_edge(clk)) thenif(pause='1') then -- op_cmd <= "0001000001000001"; op_cmd <= cmdCreate(OPCMD_FUN_ADD,      -- 算式单元功能选择 OPCMD_ITEM_DISENB,  -- 算式单元使能 OPCMD_ITEM_DISENB,  -- Y寄存器片选  OPCMD_ITEM_DISENB,  -- Y寄存器写使能  OPCMD_ITEM_DISENB,  -- X寄存器片选  OPCMD_ITEM_DISENB,  -- X寄存器写使能  OPCMD_ITEM_ENB,     -- ACC寄存器片选  OPCMD_ITEM_DISENB,  -- ACC寄存器写使能  OPCMD_ITEM_DISENB,  -- RAM存储器写使能  OPCMD_ITEM_DISENB,  -- ZPG存储器写使能  OPCMD_ITEM_DISENB,  -- PPU存储器写使能  OPCMD_ITEM_DISENB,  -- STACK存储器写使能  OPCMD_ITEM_ENB      -- PC寄存器写使能  ); end if; current_state <= future_state; end if;end process; process(current_state,rom_code) -- rom chip select & postion move signal -- procedure romshift(rd: in std_logic; mv: in std_logic) is  -- begin --     pc_cs <= rd; --     pc_ent <= mv; -- end romshift; begin -- 状态机指令解析 case current_state is when PRCSTATU_READY => -- 取指令操作码 case rom_code is when X"6D" => -- ADC abs cmd_type <= INDT_ABS; acc_temp <= mem_data; mem_data <= not(status); -- when 16#E8# => res := 1; -- INX -- when 16#C8# => res := 1; -- INY -- when 16#CA# => res := 1; -- DEX -- when 16#88# => res := 1; -- DEY -- when 16#0A# => res := 1; -- ASL -- when 16#4A# => res := 1; -- LSR -- when 16#2A# => res := 1; -- ROL -- when 16#6A# => res := 1; -- ROR -- when 16#00# => res := 1; -- BRK-- when 16#40# => res := 1; -- RTI -- when 16#60# => res := 1; -- RTS -- when 16#18# => res := 1; -- CLC -- when 16#D8# => res := 1; -- CLD -- when 16#58# => res := 1; -- CLI -- when 16#B8# => res := 1; -- CLV -- when 16#38# => res := 1; -- SEC -- when 16#F8# => res := 1; -- SED -- when 16#78# => res := 1; -- SEI -- when 16#AA# => res := 1; -- TAX -- when 16#A8# => res := 1; -- TAY -- when 16#BA# => res := 1; -- TSX -- when 16#8A# => res := 1; -- TXA -- when 16#9A# => res := 1; -- TXS -- when 16#98# => res := 1; -- TYA -- when 16#48# => res := 1; -- PHA -- when 16#08# => res := 1; -- PHP -- when 16#68# => res := 1; -- PLA -- when 16#28# => res := 1; -- PLP -- when 16#EA# => res := 1; -- NOP -- when 16#6D# => res := 3; -- ADC abs -- when 16#7D# => res := 3; -- ADC abs,x -- when 16#79# => res := 3; -- ADC abs,y -- when 16#EE# => res := 3; -- INC abs -- when 16#FE# => res := 3; -- INC abs,x -- when 16#ED# => res := 3; -- SBC abs -- when 16#FD# => res := 3; -- SBC abs,x -- when 16#F9# => res := 3; -- SBC abs,y -- when 16#CE# => res := 3; -- DEC abs -- when 16#DE# => res := 3; -- DEC abs,x -- when 16#2D# => res := 3; -- AND abs -- when 16#3D# => res := 3; -- AND abs,x-- when 16#39# => res := 3; -- AND abs,y-- when 16#4D# => res := 3; -- EOR abs-- when 16#5D# => res := 3; -- EOR abs,x -- when 16#59# => res := 3; -- EOR abs,y -- when 16#0D# => res := 3; -- ORA abs -- when 16#11# => res := 3; -- ORA (abs),y -- when 16#1D# => res := 3; -- ORA abs,x -- when 16#19# => res := 3; -- ORA abs,y -- when 16#2C# => res := 3; -- BIT abs -- when 16#0E# => res := 3; -- ASL abs -- when 16#1E# => res := 3; -- ASL abS,x -- when 16#4E# => res := 3; -- LSR abs -- when 16#5E# => res := 3; -- LSR abs,x -- when 16#2E# => res := 3; -- ROL abs-- when 16#3E# => res := 3; -- ROL abs,x-- when 16#6E# => res := 3; -- ROR abs-- when 16#7E# => res := 3; -- ROR abs,x-- when 16#4C# => res := 3; -- JMP abs-- when 16#6C# => res := 3; -- JMP (abs)-- when 16#20# => res := 3; -- JSR oper -- when 16#CD# => res := 3; -- CMP abs -- when 16#DD# => res := 3; -- CMP abs,x -- when 16#D9# => res := 3; -- CMP abs,y -- when 16#EC# => res := 3; -- CPX abs -- when 16#CC# => res := 3; -- CPY abs -- when 16#AD# => res := 3; -- LDA abs -- when 16#BD# => res := 3; -- LDA abs,x -- when 16#B9# => res := 3; -- LDA abs,y -- when 16#AE# => res := 3; -- LDX abs -- when 16#BE# => res := 3; -- LDX abs,y -- when 16#AC# => res := 3; -- LDY abs -- when 16#BC# => res := 3; -- LDY abs,X -- when 16#8D# => res := 3; -- STA abs-- when 16#9D# => res := 3; -- STA abs,x-- when 16#99# => res := 3; -- STA abs,y-- when 16#8E# => res := 3; -- STX abs-- when 16#8C# => res := 3; -- STY abswhen others => null; end case; when others => NULL; end case; end process;
end arch_controller; 

简单的编写了CPU架构的ROM读取读取及更新部份,编译后依然得到的逻辑数为0

这就有点儿郁闷了,这个问题是因为什么问题造成的呢?

难不成问题是输入输出引脚间没有对应关系吗?我这是一个CPU,它虽然有输出引脚,但是却是键盘接口与显示器接口,那下面我就先随便的添加一个简单的外部IO试试看是不是因为这个原因吧!

在FPGA开发板上玩《超级玛丽》之笔记 -(2)重构2A03CPU相关推荐

  1. fpga驱动rgb液晶屏_正点原子开拓者FPGA开发板资料连载第五十四章基于的数字识别实验...

    1)实验平台:正点原子开拓者FPGA 开发板 2)摘自<开拓者FPGA开发指南>关注官方微信号公众号,获取更多资料:正点原子 3)全套实验源码+手册+视频下载地址:http://www.o ...

  2. 在S3C6410开发板上的LED驱动程序

    这两天写了个LED驱动程序,网上也看了好多的帖子. 开始思路很清晰了,就是先看电路图,发现LED灯是接在GPM端口上的, 然后看S3C6410数据手册,先向GPMCON口写命令字,让GPM0-5设置为 ...

  3. 共阳数码管段码表_正点原子开拓者FPGA开发板资料连载第十一章 静态数码管显示实验...

    1)实验平台:正点原子开拓者FPGA 开发板 2)摘自<开拓者FPGA开发指南>关注官方微信号公众号,获取更多资料:正点原子 3)全套实验源码+手册+视频下载地址:http://www.o ...

  4. 国产荔枝糖FPGA开发板实现FM发射

    之前在ZEDBOARD上实现了FM发射,移植到荔枝糖FPGA开发板上,运行异常,抓波形看,波形紊乱,由于最高时钟为450M,估计是荔枝糖FPGA开发板跑不了这么高,那就降频吧,降到18M果然可以发射了 ...

  5. 基于FPGA开发板使用Verilog设计PWM呼吸灯实验

    基于FPGA开发板使用Verilog设计PWM呼吸灯实验 1,实验原理 2,实验模块设计 2.1 RTL设计,呼吸灯模块设计 2.2,测试数据,下载到FPGA开发板板级的数据 2.3,两个模块综合的n ...

  6. VHDL编写多功能数字钟,spartan3 FPGA开发板硬件实现-学习笔记

    VHDL编写多功能数字钟,spartan3 FPGA开发板硬件实现-学习笔记 多功能数字钟硬件测试视频: https://www.bilibili.com/video/av62501230 1.数字钟 ...

  7. html抽奖源码_开源FPGA开发板OpenICE 介绍及抽奖

    首先呢,先强调一遍,我做板子不是为了挣钱,因为国内目前的形式比较严峻,只是为了体验一下开源的工具和环境,也为了后人能对FPGA有个新的认识,所以不会触碰到任何人的蛋糕. 本来今天不准备发文了,还是熬夜 ...

  8. 开源RISC-V 项目Freedom在Arty-7-100T开发板上的实现

    开源RISC-V 项目Freedom在Arty-7-100T开发板上的实现 1.获取Freedom项目源码 Freedom项目开源的地址为https://github.com/sifive/freed ...

  9. 开源FPGA开发板-OpenICE 介绍及抽奖

    首先呢,先强调一遍,我做板子不是为了挣钱,因为国内目前的形式比较严峻,只是为了体验一下开源的工具和环境,也为了后人能对FPGA有个新的认识,所以不会触碰到任何人的蛋糕. 本来今天不准备发文了,还是熬夜 ...

  10. 【小月电子】ALTERA FPGA开发板系统学习教程-LESSON12 IPCORE核之FIFO详细教程

    ALTERA FPGA IPCORE核之FIFO详细教程 若要观看该博客配套的视频教程,可点击此链接 一. FIFO简介 FIFO: 是英文first in first out的缩写,即先进先出,指的 ...

最新文章

  1. go 获得 mysql 实际运行 SQL,Golang实践录:一个数据库迁移的代码记录
  2. 打印二叉搜索树的叶子结点_求孩子兄弟树叶子节点数目
  3. Water Balance CodeForces - 1300E
  4. 电子计算机职业40201,天津滨海中等专业学校
  5. 云服务器主体信息可以变更吗,云服务器备案号是什么?备案号存在能否更换云服务器?...
  6. qtreewidgetitem 文字内存太长换行_table文字溢出显示省略号问题
  7. 如何使frame能居中显示
  8. 翻译Java虚拟机的结构
  9. FPGA 独立按键消抖
  10. 基于MT5的沪深股票回测二 导入历史数据
  11. Spring Boot 3.x特性-JSON(gson,jackson,json-b,fastjson)
  12. D. Pythagorean Triples (math、暴力)
  13. ffmpeg学习:滤镜(实现视频缩放,裁剪,水印等) -
  14. MaxEnt软件的使用
  15. 关于Java中Match类的appendReplacement()方法的一个坑{ character to be escaped }
  16. 粒子群算法python(含例程代码与详解)
  17. 和鲸社区的滴滴出行数据分析项目
  18. 交换机虚拟化和堆叠的区别_交换机级联与堆叠有何区别?(内含堆叠方法)
  19. 2021年电工(中级)考试题库及电工(中级)最新解析
  20. 重庆主城跑步地图|总有一条跑道适合你

热门文章

  1. TCR历史论文多久能发表?
  2. Unity 2D横版闯关游戏 (JUNGLE RULES)
  3. Data Management Platform 数据管理平台全接触
  4. springmvc防xss脚本注入攻击,springmvc过滤html和js标签,html和js标签转义
  5. 【网络安全】入侵防御系统
  6. 人人商城互动直播(与通信服务器连接失败)
  7. 中国移动通信互联网短信网关接口协议 (China Mobile Peer to Peer, CMPP) (V2.0)
  8. pycharm一些常用的搜索快捷键
  9. MATLAB做三维图时值为0的点不画出来
  10. 小尺寸2.4G SMD贴片天线方案 CA-C03 CrossAir贴片天线