加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

FPGA设计――SPI Flash启动之MC8051设计

发布时间:2020-12-15 19:57:37 所属栏目:百科 来源:网络整理
导读:1. 概述 本设计采用FPGA技术,在FPGA中实现8051单片机的软核,将外部SPI Flash中的代码数据加载到FPGA内部ram,然后复位MC8051,实现外部flash启动MC8051。 2. 系统框图 8051采用Oregano Systems公司开源的MC8051软核。SPI Flash采用W25Q16芯片存储8051的代

1. 概述

本设计采用FPGA技术,在FPGA中实现8051单片机的软核,将外部SPI Flash中的代码数据加载到FPGA内部ram,然后复位MC8051,实现外部flash启动MC8051。


2. 系统框图

8051采用Oregano Systems公司开源的MC8051软核。SPI Flash采用W25Q16芯片存储8051的代码程序。系统框图如下:

wKiom1hzKsSAa3_iAABHO8So9II344.jpg


3. MC8051简介

Oregano Systems的8051单片机采用VHDL语言开发,具有如下特点:

  • 采用完全同步设计

  • 指令集和标准 8051 微控制器完全兼容

  • 指令执行时间为 1~4 个时钟周期,执行性能优于标准 8051 微控制器 8 倍左右

  • 用户可选择定时器/计数器、串行接口单元的数量

  • 新增了特殊功能寄存器用于选择不同的定时器/计数器、串行接口单元

  • 可选择是否使用乘法器(乘法指令 MUL)

  • 可选择是否使用除法器(除法指令 DIV)

  • 可选择是否使用十进制调整功能(十进制调整指令 DA)

  • I/O 口不复用

  • 内部带 256Bytes RAM

  • 最多可扩展至 64Kbytes 的 ROM 和 64Kbytes 的 RAM

  • 最多可扩展至 64Kbytes 的 ROM 和 64Kbytes 的 RAM

MC8051 IP Core的顶层结构如下图所示:

wKiom1hzK_ijretGAACSF5cD3LI646.jpg


4. MC8051移植

在mc8051_p.vhd中,更改C_IMPL_N_TMR、C_IMPL_N_SIU、C_IMPL_N_EXT的值可以定义定时器和外部中断的数量。

??-----------------------------------------------------------------------------
??--?Select?how?many?timer/counter?units?should?be?implemented
??--?Default:?1
??constant?C_IMPL_N_TMR?:?integer?:=?1;
??-----------------------------------------------------------------------------

??-----------------------------------------------------------------------------
??--?Select?how?many?serial?interface?units?should?be?implemented
??--?Default:?C_IMPL_N_TMR?---(DO?NOT?CHANGE!)---		?????
??constant?C_IMPL_N_SIU?:?integer?:=?C_IMPL_N_TMR;
??-----------------------------------------------------------------------------
				?????
??-----------------------------------------------------------------------------
??--?Select?how?many?external?interrupt-inputs?should?be?implemented
??--?Default:?C_IMPL_N_TMR?---(DO?NOT?CHANGE!)---
??constant?C_IMPL_N_EXT?:?integer?:=?C_IMPL_N_TMR;
??-----------------------------------------------------------------------------

在mc8051_p.vhd中,还可以选择需要的指令,可选的指令有MUL/DIV/DA。

??-----------------------------------------------------------------------------
??--?Select?whether?to?implement?(1)?or?skip?(0)?the?multiplier
??--?Default:?1
??constant?C_IMPL_MUL?:?integer?:=?1;
??-----------------------------------------------------------------------------

??-----------------------------------------------------------------------------
??--?Select?whether?to?implement?(1)?or?skip?(0)?the?divider
??--?Default:?1
??constant?C_IMPL_DIV?:?integer?:=?1;
??-----------------------------------------------------------------------------
				???
??-----------------------------------------------------------------------------
??--?Select?whether?to?implement?(1)?or?skip?(0)?the?decimal?adjustment?command
??--?Default:?1
??constant?C_IMPL_DA??:?integer?:=?1;
??-----------------------------------------------------------------------------

在FPGA中用内部的ram资源构建一个rom和一个ram以供8051使用,其中rom需为双端口,用于spi_flash_controller加载flash中的程序。


5. SPI Flash简介

SPI Flash芯片是由8192个页组成,每页大小为256字节。16页组成一个扇区,128/256页组成一个块,其结构框图如下:

wKiom1hzL5-RJK6rAAJ7zmSW5O0666.jpg

SPI Flash的读写指令如下:

wKiom1hzMLTR496LAADlQgotXyQ714.jpg

wKioL1hzMLXA7Ml4AAErQzm_NKU053.jpg


6. SPI Flash控制器设计

SPI Flash的读写时序如下:其他操作的时序可查看spi flash datasheet。

wKioL1hzMmPzX9vkAADSU9g8Ejs556.jpg

wKiom1hzMmSzWuCQAADH3hPyhJA182.jpg

控制器状态机设计如下:

wKiom1hzMr7xzzozAADNBE4d4jM840.jpg


SPI Flash加载控制逻辑代码如下:

//file?name:	spi_flash_load.v
//author:		shugen.yin
//date:			2017.1.5
//function:		load?code?from?spi?flash?to?dram
//log:

module?spi_flash_load(
	//Global?signal
	input?clk,input?rst_n,//signal?from?and?to?SPI?reader
	output?reg?rd_start,output?reg?[31:0]?rd_addr,output?reg?[31:0]?rd_length,input??????[7:0]?rd_data,input??????rd_data_valid,input??????read_busy,//signal?to?mc8051
	input??????[15:0]?rdaddress,output?????[7:0]??data_out,output?????reg????reset

);

reg?[15:0]?wraddress;

always?@(posedge?clk)
	if(rd_data_valid)
		wraddress?<=?wraddress?+?1'b1;
	else
		wraddress?<=?wraddress;
		

dpram	dpram_inst?(
	.clock?(?clk?),.data?(?rd_data?),.rdaddress?(?rdaddress?),.wraddress?(?wraddress?),.wren?(?rd_data_valid?),.q?(?data_out?)
	);

reg?[15:0]?spi_cnt;

always?@(posedge?clk)
	if(spi_cnt<=16'h0fff)
		spi_cnt?<=?spi_cnt?+?1'b1;
	else
		spi_cnt?<=?spi_cnt;

always?@(posedge?clk)
	if(spi_cnt==1)
	begin
		rd_start?<=?1'b1;
		rd_addr??<=?'h0;
		rd_length<=?'h1000;
	end
	else
	begin
		rd_start?<=?1'b0;
		rd_addr??<=?rd_addr;
		rd_length<=?rd_length;	
	end	

	
always?@(posedge?clk)
	if(spi_cnt==16'h1000)
	???reset?<=?0;
	else
		reset?<=?1'b1;

endmodule


7. MC8051 C语言开发

这里采用Keil uVision4作为开发平台,用到MC8051的I/0和定时器设备,代码设计如下:

#include?<reg51.h>

sbit?P00=P0^0;

char?i=100;

unsigned?char?led=0;

void?Timer0_init(void)
{
	TMOD?=?0x01;	//set?timer0?as?mode-1
	TH0??=?0xee;	
	TL0??=?0x00;
	P00??=?0;
	EA???=?1;		//enable?interrupt
	ET0??=?1;		//enable?timer0?interrupt
	TR0??=?1;		//Trigger?Timer0	
}

void?main(void)
{
	Timer0_init();

	while(1){};
}

void?Timer0_int(void)?interrupt?1
{
	TH0?=?0xee;
	TL0?=?0x00;
	i--;
	if(i<=0)
	{
		led??=?~led;
		i????=?100;
	}	
	P00?=?led;
}

编译KEIL工程,得到hex文件:将KEIL生成的hex文件烧写道SPI Flash中。

wKiom1hzNXzR7VWyAAAvPLcpwAI993.jpg


8.?FPGA系统逻辑代码设计

FPGA系统逻辑代码顶层设计如下:

//file?name			:?top_fpga.v
//data				:?2017.1.9
//author			:?shugen.yin
//function			:?top?of?project
//log				:

module?top_fpga(
	//global?signal
	input?clk,//led
	output?[1:0]?led
	);

//----------------MC8051------------------
wire?int0_i;
wire?int1_i;
wire?all_t0_i;
wire?all_t1_i;
wire?[7:0]?p0_i;
wire?[7:0]?p1_i;
wire?[7:0]?p2_i;
wire?[7:0]?p3_i;

(*?keep?*)wire?[7:0]?p0_o;
(*?keep?*)wire?[7:0]?p1_o;
(*?keep?*)wire?[7:0]?p2_o;
(*?keep?*)wire?[7:0]?p3_o;

mc8051_top?mc8051_top_inst
(
	.clk(clk)?,//?input??clk_sig
	.reset(spi_load_reset)?,//?input??reset_sig
	.int0_i(int0_i)?,//?input?[0:0]?int0_i_sig
	.int1_i(int1_i)?,//?input?[0:0]?int1_i_sig
	.all_t0_i(1'b0)?,//?input?[0:0]?all_t0_i_sig
	.all_t1_i(1'b0)?,//?input?[0:0]?all_t1_i_sig
	.p0_i(p0_i)?,//?input?[7:0]?p0_i_sig
	.p1_i(p1_i)?,//?input?[7:0]?p1_i_sig
	.p2_i(p2_i)?,//?input?[7:0]?p2_i_sig
	.p3_i(p3_i)?,//?input?[7:0]?p3_i_sig
	.p0_o(p0_o)?,//?output?[7:0]?p0_o_sig
	.p1_o(p1_o)?,//?output?[7:0]?p1_o_sig
	.p2_o(p2_o)?,//?output?[7:0]?p2_o_sig
	.p3_o(p3_o)?,?	//?output?[7:0]?p3_o_sig
	
	.dram_adr_o(spi_load_address)?,//output?address
	.dram_data_i(spi_load_data)		//input?data
);

assign?led?=?{p0_o[0],~p0_o[0]};

//----------------SPI?Flash------------------
wire?			rd_start;
wire?[31:0]?rd_addr;
wire?[31:0]?rd_length;
wire?[7:0]??rd_data;
wire?		rd_data_valid;
wire		read_busy;

spi_flash_reader?spi_flash_reader_inst
(
	//global?signal
	.clk(clk),.rst_n(rst_n),//SPI?master?port
	.spi_dclk(flash_clk),.spi_cs_n(flash_cs_n),.spi_so(flash_mosi),.spi_si(flash_miso),//export?port
	.rd_start(rd_start),.rd_addr(rd_addr),.rd_length(rd_length),.rd_data(rd_data),.rd_data_valid(rd_data_valid),.read_busy(read_busy)
);

wire?[15:0]?spi_load_address;
wire?[7:0]??spi_load_data;
wire????????spi_load_reset;

spi_flash_load?spi_flash_load_inst
(
	.clk(clk)?,????????????????????//?input??clk_sig
	.rst_n(rst_n)?,????????????????//?input??rst_n_sig
	.rd_start(rd_start)?,???????????//?output??rd_start_sig
	.rd_addr(rd_addr)?,????????????//?output?[31:0]?rd_addr_sig
	.rd_length(rd_length)?,?????????//?output?[31:0]?rd_length_sig
	.rd_data(rd_data)?,????????????//?input?[7:0]?rd_data_sig
	.rd_data_valid(rd_data_valid)?,//?input??rd_data_valid_sig
	.read_busy(read_busy)?,????????//?input??read_busy_sig
	.rdaddress(spi_load_address)?,//?output?[11:0]?rdaddress_sig
	.data_out(spi_load_data),?	????//?output?[7:0]?data_out_sig
	.reset(spi_load_reset)
);

endmodule


9. 最终结果

在Quartus II 13.1平台下,编译完成后,将sof文件下载到板卡上,LED交替闪烁。

wKioL1hzOByQbjL3AAEGLxYf7Is750.jpg

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读