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

1. 概述

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

2. 系统框图

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

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的顶层结构如下图所示:

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页组成一个块,其结构框图如下:

SPI Flash的读写指令如下:

6. SPI Flash控制器设计

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

控制器状态机设计如下:

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中。

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,
	input rst_n,

	//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交替闪烁。

时间: 2024-08-04 13:13:22

FPGA设计——SPI Flash启动之MC8051设计的相关文章

Atitit.面向接口的web&#160;原理与设计重写&#160;路由启动绑定配置url&#160;router&#160;rewriting&#160;urlpage&#160;&#160;mvc&#160;mvp的&#160;java&#160;c#.net&#160;php&#160;js

Atitit.面向接口的web 原理与设计重写 路由启动绑定配置url router rewriting urlpage  mvc mvp的 java c#.net php js 原理 通过vm带入启动参数    制定ioc配置文件 绑定各项.. <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <ifra

app启动页的设计技巧(一)

虽然,每一个APP的启动页界面设计是需要按使用场景设计的.但是每一个APP启动页的存在的意义与APP产品定位.APP运营策略有关的. 第一部分:对于设计一个好的APP启动页作品,必须满足这三个特征 认真观察,很容易归纳出欢迎页有以下的三个特征: 1.简单:在启动页中,文案是极为简短精炼的,而启动页一般由一张图片和一句文案组成: 2.直接:启动页中的文字表述简单直接,基本没有过多的修饰性词语: 3.图为主,文为辅:启动页中,图片约占三分之二的区域,文字约占三分之一的区域 第二部分:简单易学的APP

DM365视频处理流程/DM368 NAND Flash启动揭秘

DM365的视频处理涉及到三个相关处理器,分别是视频采集芯片.ARM处理器和视频图像协处理器(VICP),整个处理流程由ARM核协调.视频处理主要涉及三个处理流程,分别是视频采集.视频编码和对编码后的视频的处理,为了提高性能,通常为每个处理流程提供一个处理线程.视频采集  TVP5146将采集到的视频数据转化为数字信号,并将这些数据送入DM365的BT656接口,然后通过Resize得到所需要的分辨率,然后将这些数据写入到指定的内存中,这些内存空间由cmem模块分配.cmem模块用于分配连续的存

【转】SPI FLASH与NOR FLASH的区别 详解SPI FLASH与NOR FLASH的不一样

转自:http://m.elecfans.com/article/778203.html 本文主要是关于SPI FLASH与NOR FLASH的相关介绍,并着重对SPI FLASH与NOR FLASH的区别进行了详细的区分. SPI FLASH 首先它是个Flash,Flash是什么东西就不多说了(非易失性存储介质),分为NOR和NAND两种(NOR和NAND的区别本篇不做介绍).SPI一种通信接口.那么严格的来说SPI Flash是一种使用SPI通信的Flash,即,可能指NOR也可能是NAN

u-boot-2014.10移植第25天----nand flash启动(三)

硬件平台:tq2440 开发环境:Ubuntu-3.11 u-boot版本:2014.10 本文允许转载,请注明出处:http://blog.csdn.net/fulinus 在实现u-boot从nand flash启动之前,我们将前面asm_led程序放在nand flash第一个块的前4Kbit之中,因为asm_led没有系统初始化功能,所以还需要将bootstrap程序,放在nand flash的0地址处.bootstrap初始化完2440后,跳转到asm_led程序去执行.这对于掌握从n

【网页设计】——网络运营“眼”中的设计有何不同

有需求才会有市场.基于各企业的发展需求和网站运营的目的不同,网页的设计也是各有特色,颇有百花争艳,一求独领群芳的发展趋势.谈到设计,我认为都会有相对固定的"潜规则"和样式的,不是说网页设计的死板,只是因为究其原因,所有的网页设计的最后,都是为了更好的达到盈利的效果. 工欲善其事必先利其器.做网络运营这一行的,首先是对设计工具的基本了解和会如何使用,还需要具有相当的知识储备.可用于网页设计的:Dreamwave,该软件除了拥有强大的设计功能,更重要的是设计成品能获得许多的浏览器的支持.还

转载:关于HI3516A 使用SDK06版本更换DDR和SPI FLASH遇到的问题和解决方法

HI3516A 更换DDR 和 FLASH 最近有新的需求需要使用SDK06版本,以及在硬件上更换了DDR和 FLASH,遇到了一些问题,这段时间搜索了很多hisi的资料和帖子,大概做了如下的总结,希望对大家有帮助,若有错误的地方或遗漏的地方,请指出.谢谢. 更换DDR 和 flash,则需要更新uboot,因为里面包含了DDR和flash的配置. 首先需要对hisi的uboot有所了解. hisi uboot分解为两部分.前面一部分为DDR的参数和其他寄存器的配置,总过大小为4K具体的地址为从

(电工基地笔记)Vivado固化至SPI Flash

如果从头开始做SPI Flash固化是有一些麻烦的,要在完成综合之后,打开 synthesized Design (图) (图) 然后在synthesized Design打开状态下,选择Tools->Edit Device Properties编辑器件属性 (图) 我们这个FPGA有16MFlash,是Master SPIx1,大家有兴趣可以看一下Xilinx官网配置,你在此处修改都会保存在已经激活的xdc文件 (图) (图) (图) Finish就可以了,把synthesis去掉 (图) 我

五步打造APP节日主题设计:以Lofter新年图标设计为例

我们需要做有依据,有逻辑,有理念的设计,需要发散思维,整合创意,严谨输出,让设计经得起推敲 前言 ? 2018年春节已远去,一直想把Lofter新年Logo设计思路分享给大家,直到现在才整理出来,希望这篇文章能给大家一些思路和参考. 每当过节的时候,市场上大大小小的APP icon都进行了节日换装,作为视觉设计师,如何设计出与产品品牌相符合并能营造出节日氛围的设计是我们需要思考的.下面以Lofter新年图标设计为例,分享一下当时的设计思路和方法. Lofter是网易产品中资历比较老的一款产品了,