1. Overview
This design uses the FPGA technology, realizes the 8051 monolithic microcomputer soft core in the FPGA, the external SPI Flash code data loads into the FPGA internal RAM, then resets the MC8051, realizes the external flash startup MC8051.
2. System Block Diagram
8051 uses Oregano Systems Inc. open source MC8051 soft core. SPI Flash uses the W25Q16 chip to store 8051 of code programs. The system diagram is as follows:
650) this.width=650; "src=" http://s2.51cto.com/wyfs02/M02/8C/A7/wKiom1hzKsSAa3_iAABHO8So9II344.jpg "title=" Fpga_ 8051_block.jpg "width=" "height=" 364 "border=" 0 "hspace=" 0 "vspace=" 0 "style=" width:320px;height:364px; "alt=" Wkiom1hzkssaa3_iaabho8so9ii344.jpg "/>
3. MC8051 Introduction
Oregano Systems's 8051 microcontroller uses VHDL language development, has the following characteristics:
Designed with complete synchronization
Instruction set is fully compatible with standard 8051 microcontrollers
Instruction execution time is 1~4 clock cycle, execution performance is better than standard 8051 microcontroller about 8 times times
User selectable Timer/counter, serial interface Unit number
Special function registers are added to select different timers/counters, serial interface units
Choose whether to use multipliers (multiplication instruction MUL)
You can choose whether to use the divider (Division instruction DIV)
You can choose whether to use the decimal adjustment function (decimal adjustment instruction DA)
I/O port no longer available
Internal with 256Bytes RAM
Expandable up to 64Kbytes ROM and 64Kbytes of RAM
Expandable up to 64Kbytes ROM and 64Kbytes of RAM
The top-level structure of the MC8051 IP core is as follows:
650) this.width=650; "src=" http://s4.51cto.com/wyfs02/M02/8C/A7/wKiom1hzK_ijretGAACSF5cD3LI646.jpg "title=" MC8051 _block.jpg "alt=" Wkiom1hzk_ijretgaacsf5cd3li646.jpg "/>
4. MC8051 Transplant
In mc8051_p.vhd, changing the values of C_IMPL_N_TMR, C_impl_n_siu, and C_impl_n_ext can define the number of timers and external interrupts.
----------------------------------------------------------------------------- -- 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; ---------- -------------------------------------------------------------------
In Mc8051_p.vhd, you can also select the required directives, and the optional directives have 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; --------------------------- --------------------------------------------------
Build a ROM and a RAM for 8051 using internal RAM resources in the FPGA, where the ROM needs to be a dual port for Spi_flash_controller to load programs in Flash.
5. Introduction to SPI Flash
The SPI Flash chip is made up of 8,192 pages with a size of 256 bytes per page. 16 pages form a sector, and 128/256 pages form a block with the following structural diagram:
650) this.width=650; "src=" http://s4.51cto.com/wyfs02/M02/8C/A7/wKiom1hzL5-RJK6rAAJ7zmSW5O0666.jpg "title=" Flash_ Block.jpg "alt=" Wkiom1hzl5-rjk6raaj7zmsw5o0666.jpg "/>
The read and write instructions for SPI Flash are as follows:
650) this.width=650; "src=" Http://s3.51cto.com/wyfs02/M00/8C/A7/wKiom1hzMLTR496LAADlQgotXyQ714.jpg "style=" width : 650px;height:249px; "title=" read_cmd.jpg "width=" 650 "height=" 249 "border=" 0 "hspace=" 0 "vspace=" 0 "alt=" Wkiom1hzmltr496laadlqgotxyq714.jpg "/>
650) this.width=650; "src=" Http://s3.51cto.com/wyfs02/M00/8C/A3/wKioL1hzMLXA7Ml4AAErQzm_NKU053.jpg "style=" width : 650px;height:430px; "title=" write_cmd.jpg "width=" 650 "height=" 430 "border=" 0 "hspace=" 0 "vspace=" 0 "alt=" Wkiol1hzmlxa7ml4aaerqzm_nku053.jpg "/>
6. SPI Flash Controller Design
The read-write timing of SPI Flash is as follows: the timing of other operations can be viewed in SPI Flash datasheet.
650) this.width=650; "src=" Http://s5.51cto.com/wyfs02/M00/8C/A4/wKioL1hzMmPzX9vkAADSU9g8Ejs556.jpg "style=" width : 700px;height:268px; "title=" spi_flash_read_wave.jpg "width=" "height=" "268" border= "0" hspace= "0" vspace= "0" alt= " Wkiol1hzmmpzx9vkaadsu9g8ejs556.jpg "/>
650) this.width=650; "src=" Http://s4.51cto.com/wyfs02/M01/8C/A7/wKiom1hzMmSzWuCQAADH3hPyhJA182.jpg "style=" width : 700px;height:432px; "title=" spi_write_wave.jpg "width=" "height=" "432" border= "0" hspace= "0" vspace= "0" alt= " Wkiom1hzmmszwucqaadh3hpyhja182.jpg "/>
The controller state machine is designed as follows:
650) this.width=650; "src=" http://s1.51cto.com/wyfs02/M02/8C/A7/wKiom1hzMr7xzzozAADNBE4d4jM840.jpg "title=" Flash_ State.jpg "width=" "height=" "border=" 0 "hspace=" 0 "vspace=" 0 "style=" width:600px;height:750px; "alt=" Wkiom1hzmr7xzzozaadnbe4d4jm840.jpg "/>
The SPI Flash load Control logic code is as follows:
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 signalinput clk,input rst_n,//signal from and to SPI readeroutput 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 mc8051input [15:0] rdaddress,output [7:0] data_out,output Reg reset); reg [15:0] wraddress;always @ (POSEDGE&NBSP;CLK) if (rd_data_ Valid) wraddress <= wraddress + 1 ' B1;ELSEWRADDRESS&NBSP;<=&NBSP;WRADDRESS;DPRAMDPRAM_ inst (.clock (&NBSP;CLK ),.data ( rd_data ),.rdaddress ( rdaddress ),.wraddress ( wraddress ),.wren ( rd_data_valid ),.q ( data_out ));reg [15:0] spi_cnt;always @ (POSEDGE&NBSP;CLK) if (spi_cnt<=16 ' h0fff) spi_cnt <= spi_cnt + 1 ' b1;elsespi_cnt <= spi_cnt;always @ (POSEDGE&NBSP;CLK) if (spi_cnt==1) beginrd_start <= 1 ' b1;rd_addr <= ' h0;rd_length<= ' h1000;endelsebeginrd_start <= 1 ' b0;rd_addr <= rd_addr;rd_length<= rd_length;endalways @ (POSEDGE&NBSP;CLK) if ( Spi_cnt==16 ' h1000) reset <= 0;elsereset <= 1 ' B1;endmodule
7. MC8051 C language Development
The Keil uVision4 is used as a development platform for MC8051 i/0 and timer devices, and the code is designed as follows:
#include <reg51.h>sbit p00=p0^0;char i=100;unsigned char led=0;void timer0_init (void) {tmod = 0x01;//set Timer0 as M Ode-1th0 = 0xEE; TL0 = 0x00; P00 = 0; EA = 1;//enable interruptET0 = 1;//enable Timer0 interruptTR0 = 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;}
Compile Keil project, get hex file: Keil generated hex file burned in SPI Flash.
650) this.width=650; "src=" http://s5.51cto.com/wyfs02/M02/8C/A7/wKiom1hzNXzR7VWyAAAvPLcpwAI993.jpg "title=" c51_ Build.jpg "alt=" Wkiom1hznxzr7vwyaaavplcpwai993.jpg "/>
8. FPGA System Logic code design
FPGA system Logic code top-level design is as follows:
File name: top_fpga.v//data: 2017.1.9//author: shugen.yin//function: top of &NBSP;PROJECT//LOG:MODULE&NBSP;TOP_FPGA (//global signalinput clk,input rst_n,//ledoutput [ 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;wireread_busy;spi_flash_reader spi_flash_reader_inst (//GLOBAL&NBSP;SIGNAL.CLK (CLK),. Rst_n (Rst_n),//SPI&NBSP;MASTER&NBSP;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) , &NBSP;&NBSP;&NBSP;//&NBSP;OUTPUT&NBSP;&NBSP;RD_START_SIG.RD_ADDR (RD_ADDR) , // output [31:0] rd_addr_sig.rd_length (Rd_length) , &nbsP; // 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. Final results
In the Quartus II 13.1 Platform, after the compilation is complete, the SOF file is downloaded to the board, and the LED flashes alternately.
650) this.width=650; "src=" http://s2.51cto.com/wyfs02/M02/8C/A4/wKioL1hzOByQbjL3AAEGLxYf7Is750.jpg "title=" Spi_ Fpga_result.jpg "width=" "height=" 260 "border=" 0 "hspace=" 0 "vspace=" 0 "style=" width:750px;height:260px; "alt=" Wkiol1hzobyqbjl3aaeglxyf7is750.jpg "/>
This article is from the "Shugenyin blog" blog, make sure to keep this source http://shugenyin.blog.51cto.com/4259554/1890407
Design of MC8051 for--SPI Flash starting in FPGA design