|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
本帖最后由 weisonwsc 于 2017-4-22 19:41 编辑
mc8051官网上有FPGA实现demo例程,我就不多说了,现在讲一下我如何在此基础上进行外设扩展。整体思路:
mc8051顶层没有外设的接口,片外RAM接口封装在内部,最大支持64KB,其实大多数情况下不需要这么多,而且一般的FPGA也没有那么多资源,我们可以把内部片外RAM接口再分成两个接口,一个接口连接到外部ram上,另一个接口连到外设上。
##1
在mc8051_top.vhd文件端口声明加上外设接口
- per_data_out: out std_logic_vector(7 downto 0);
- per_data_in : in std_logic_vector(7 downto 0);
- per_adr : out std_logic_vector(15 downto 0);
- per_wr : out std_logic;
复制代码
##2
修改mc8051_top_struc.vhd文件,主要是实现内部片外RAM接口分成两个接口,这里我使用2k的片外ram,大家根据自己的情况修改
- architecture struc of mc8051_top is
-
- signal s_rom_adr: std_logic_vector(15 downto 0); -- Programmcounter =
- -- ROM-adress
- signal s_rom_data: std_logic_vector(7 downto 0); -- data input from ROM
- signal s_ram_data_out: std_logic_vector(7 downto 0); -- data output to
- -- internal RAM
- signal s_ram_data_in: std_logic_vector(7 downto 0); -- data input from
- -- internal RAM
- signal s_ram_adr: std_logic_vector(6 downto 0); -- internal RAM-adress
- signal s_ram_wr: std_logic; -- read (0)/write (1)
- -- internal RAM
- signal s_ram_en: std_logic; -- RAM-block enable
-
- signal s_datax_o: std_logic_vector(7 downto 0); -- data output to
- -- ext. RAM
- signal s_datax_i: std_logic_vector(7 downto 0); -- data input from
- -- ext. RAM
- signal s_adrx_o: std_logic_vector(15 downto 0); -- ext. RAM-adress
- signal s_wrx_o: std_logic; -- read (0)/write (1)
- -- ext. RAM
- signal s_rom_adr_sml: std_logic_vector(14 downto 0);
- signal s_ramx_adr_sml: std_logic_vector(10 downto 0);
- signal s_ramx_data_in: std_logic_vector(7 downto 0);
- signal s_ramx_data_out:std_logic_vector(7 downto 0);
- signal s_ramx_wr: std_logic;
- signal per_sel : std_logic;
- begin -- architecture structural
- s_rom_adr_sml <= std_logic_vector(s_rom_adr(14 downto 0));
- s_ramx_adr_sml <= std_logic_vector(s_adrx_o(10 downto 0));
- s_ramx_data_out<= s_datax_o ;
- s_ramx_wr <= s_wrx_o when std_logic_vector(s_adrx_o(15 downto 11))="00000" else '0' ;
- per_adr <= s_adrx_o;
- per_data_out <= s_datax_o ;
- per_wr <= s_wrx_o when std_logic_vector(s_adrx_o(15 downto 11))/="00000" else '0' ;
-
- process(clk,reset)
- begin
- if(reset='1') then per_sel<='0';
- elsif(rising_edge(clk)) then
- if std_logic_vector(s_adrx_o(15 downto 11))="00000" then per_sel<='0' ;
- else per_sel<='1';
- end if;
- end if;
- end process;
-
- s_datax_i<= s_ramx_data_in when per_sel='0' else
- per_data_in ;
-
-
- i_mc8051_core : mc8051_core
- port map(clk => clk,
- reset => reset,
- rom_data_i => s_rom_data,
- ram_data_i => s_ram_data_out,
- int0_i => int0_i,
- int1_i => int1_i,
- all_t0_i => all_t0_i,
- all_t1_i => all_t1_i,
- all_rxd_i => all_rxd_i,
- p0_i => p0_i,
- p1_i => p1_i,
- p2_i => p2_i,
- p3_i => p3_i,
- p0_o => p0_o,
- p1_o => p1_o,
- p2_o => p2_o,
- p3_o => p3_o,
- all_rxd_o => all_rxd_o,
- all_txd_o => all_txd_o,
- all_rxdwr_o => all_rxdwr_o,
- rom_adr_o => s_rom_adr,
- ram_data_o => s_ram_data_in,
- ram_adr_o => s_ram_adr,
- ram_wr_o => s_ram_wr,
- ram_en_o => s_ram_en,
- datax_i => s_datax_i,
- datax_o => s_datax_o,
- adrx_o => s_adrx_o,
- wrx_o => s_wrx_o);
-
-
- -----------------------------------------------------------------------------
- -- Hook up the general purpose 128x8 synchronous on-chip RAM.
- i_mc8051_ram : mc8051_ram
- port map ( clock => clk,
- data => s_ram_data_in,
- q => s_ram_data_out,
- address => s_ram_adr,
- wren => s_ram_wr,
- clken => s_ram_en);
- -- THIS RAM IS A MUST HAVE!!
- -----------------------------------------------------------------------------
- -----------------------------------------------------------------------------
- -- Hook up the (up to) 64kx8 synchronous on-chip ROM.
- i_mc8051_rom : mc8051_rom_32k
- port map ( clock => clk,
- q => s_rom_data,
- address => s_rom_adr_sml);
- -- THE ROM OF COURSE IS A MUST HAVE, ALTHOUGH THE SIZE CAN BE SMALLER!!
- -----------------------------------------------------------------------------
-
-
- -----------------------------------------------------------------------------
- -- Hook up the (up to) 64kx8 synchronous RAM.
- i_mc8051_ramx : mc8051_xram_2k
- port map ( clock => clk,
- data => s_ramx_data_out,
- q => s_ramx_data_in,
- address => s_ramx_adr_sml,
- wren => s_ramx_wr);
- -- THIS RAM (IF USED) CAN BE ON OR OFF CHIP, THE SIZE IS ARBITRARY.
- -----------------------------------------------------------------------------
-
- end struc;
复制代码
##3 添加外设
以下代码是一个测试外设模块,仅包含了两个寄存器,只实现了外设接口的读写。
- module ADT #(parameter
- base_adr=16'h8000
- )(
- output reg [7:0] per_dout,
- input [7:0] per_din,
- input [15:0]per_adr,
- input per_wr,
- input clk,
- input rst
- );
- reg[7:0] reg1,reg2;
- wire reg1_sel= per_adr==base_adr+16'h0001 ;
- wire reg2_sel= per_adr==base_adr+16'h0002 ;
- always@(posedge clk or posedge rst)
- if(rst)
- reg1<=8'h00;
- else if(reg1_sel && per_wr)
- reg1<=per_din;
- else ;
- always@(posedge clk or posedge rst)
- if(rst)
- reg2<=8'h00;
- else if(reg1_sel && per_wr)
- reg2<=per_din;
- else ;
- wire[7:0] reg1_dout,reg2_dout;
- assign reg1_dout=(reg1_sel)? reg1 : 8'h00;
- assign reg2_dout=(reg2_sel)? reg2 : 8'h00;
- always@(posedge clk or posedge rst)
- if(rst)
- per_dout<=8'h00;
- else
- per_dout<=reg1_dout | reg2_dout ;
- endmodule
复制代码
##4 顶层例化
此步省略
##5 测试C代码
- #include <reg51.h>
- #include "absacc.h"
- #include <intrins.h>
- #define reg1 XBYTE[0x8001]
- #define reg2 XBYTE[0x8002]
- void main(void)
- {
- unsigned char temp;
- reg1=0x5a;
- while(1)
- {
- temp=reg1;
- reg2=temp;
- temp=reg2;
- reg1=temp;
- }
-
- }
复制代码
##6 下载测试
提示 quartus 有”in-system memory conten editor" 工具,能把C51编辑的HEX文件直接下载到ROM里面(相当于下载程序),非常方便
逻辑分析仪看到读写时序
|
|