网站建设设计公司哪家好,科技杭州网站建设,wordpress添加分类到菜单,论坛网站建设流程实验目标#xff1a;
flash的普通读指令#xff0c;在指定地址开始读。可以更改地址与读的数据个数。
先发送读指令扇区地址页地址字节地址。
然后读数据。再把读到的串行数据转化为8bit的数据#xff0c;存入fifo。
然后读出FIFO中数据#xff0c;通过uart_tx模块发送…实验目标
flash的普通读指令在指定地址开始读。可以更改地址与读的数据个数。
先发送读指令扇区地址页地址字节地址。
然后读数据。再把读到的串行数据转化为8bit的数据存入fifo。
然后读出FIFO中数据通过uart_tx模块发送给上位机。
经验总结
接收数据比如接收8bit的串行数据通过miso传递。
1先接收高位。
reg [7:0] data ;
那么通过data保存miso传递的数据把串行数据转换为并行数据。
有两种常用写法
data {data[6:0],miso};
或者
data data 1 miso ;
或者写一个cnt_bit,记录保存到第几bit。
data[cnt_bit] miso ;
2,先接收低位
data {miso,data[7:1]};
data[cnt_bit] miso ;
小技巧
画时序图时不一定要先画内部信号再画输出端口信号。
按照自己的设计思路该到那个信号就画那个信号画完也不要改
写代码时按照这个思路这个画时序图的顺序编写代码。
相当于再次检查一遍即容易排错有容易编写代码。
状态机 模块框图 时序图 代码
module spi (input wire sys_clk ,input wire sys_rst_n ,input wire key_flag ,input wire miso ,output reg cs_n ,output reg sck ,output reg mosi ,output reg po_flag ,output wire [7:0] po_data
);// localparam define 一般状态机的状态定义用局部参数就可以。localparam IDLE 4b0001 ,INSTRUCT 4b0010 ,READ 4b0100 ,SEND 4b1000 ;// parameter define 指令计数器最大值用全局参数定义。parameter COMD_REA 8h03 , // comd_readADDR_SEC 8h00 , // address_secter 扇区地址ADDR_PAG 8h00 , // address_page 页地址行地址ADDR_BYT 8h00 , // assress_byte 字节地址NUM_COMD 4d4 ; // 用来记录在指令状态传递指令和地址byte数量parameter CNT_MAX_BYTE 11d300 , // 4 要读出的数据。例如 4 256CNT_MAX_SEND 20d53000 ;// reg signal define reg [3:0] state_c ;reg [3:0] state_n ;reg cnt_20_ns ;reg [2:0] cnt_bit ;reg [10:0] cnt_byte ;reg flag_b ; // flag_bytereg flagBreg ;reg flag_R_S ; // flag_bytereg flag_RSr ;reg [7:0] datInFifo ; // data_in_fiforeg flag_data ; // flag_data 采样标志信号reg flaInFifo ; // flag_in_fiforeg [19:0] cnt_send ; // uart_tx模块发送1byte数据的等待时间。reg flaSenEnd ; // 计数器cnt_send计数到CNT_MAX_SEND - 2 拉高一个时钟周期reg flag_out_fifo_reg ;// wire signal definewire empty ;wire full ;wire flaOutFif ; // flag_out_fifo wire [9:0] usedw ; // fifo中存储的数据量 wire IDLEtoINSTRUCT ;wire INSTRUCTto_READ ;wire READtoSEND ;wire SENDtoIDLE ;
/**********************************************************************/// // reg signal describe /*******状态机采用三段式描述*******/// reg [3:0] state_c ;// reg [3:0] state_n ;always (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) state_c IDLE ;else state_c state_n ;endalways (*) begincase (state_c)IDLE : if(IDLEtoINSTRUCT)state_n INSTRUCT ;else state_n IDLE ;INSTRUCT : if(INSTRUCTto_READ)state_n READ ;else state_n INSTRUCT ;READ : if(READtoSEND)state_n SEND ;else state_n READ ;SEND : if(SENDtoIDLE)state_n IDLE ;else state_n SEND ;default: state_n IDLE ;endcaseendassign IDLEtoINSTRUCT (state_c IDLE ) (key_flag) ;assign INSTRUCTto_READ (state_c INSTRUCT) (flagBreg) ; // 指令的的最后1byte发送完毕assign READtoSEND (state_c READ ) (flag_RSr) ; // 读完想要的最后1byteassign SENDtoIDLE (state_c SEND ) (flaSenEnd empty) ;// reg cnt_20_ns ;always (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n)cnt_20_ns 1b0 ;else if(state_c INSTRUCT || state_c READ)cnt_20_ns cnt_20_ns 1b1 ;else if(state_c ! INSTRUCT || state_c ! READ)cnt_20_ns 1b0 ;else cnt_20_ns 1b0 ;end// reg [2:0] cnt_bit ;always (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n)cnt_bit 3d0 ;elsecase (state_c)IDLE : cnt_bit 3d0 ;INSTRUCT: if(!cnt_20_ns sck cnt_bit 7) cnt_bit 3d0 ;else if(!cnt_20_ns sck)cnt_bit cnt_bit 1b1 ;READ : if(!cnt_20_ns sck cnt_bit 7) cnt_bit 3d0 ;else if(!cnt_20_ns sck)cnt_bit cnt_bit 1b1 ;SEND : cnt_bit 3d0 ;default : cnt_bit 3d0 ; endcaseend// reg [10:0] cnt_byte ;always (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n)cnt_byte 4d0 ;else if(cnt_bit 7 cnt_byte CNT_MAX_BYTE - 1 !cnt_20_ns sck)cnt_byte 4d0 ;else if(cnt_bit 7 !cnt_20_ns sck)cnt_byte cnt_byte 1b1 ;else cnt_byte cnt_byte ;end// reg flag_R_S ;// reg flag_b ;always (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) beginflag_b 1b0 ;flag_R_S 1b0 ;endelsecase (state_c)IDLE : beginflag_b 1b0 ;flag_R_S 1b0 ;end INSTRUCT: begin if((cnt_byte NUM_COMD - 1) (cnt_bit 7) !cnt_20_ns sck)flag_b 1b1 ;else flag_b flag_b ;flag_R_S 1b0 ;endREAD : beginif(cnt_byte NUM_COMD)flag_R_S 1b0 ;else if((cnt_byte CNT_MAX_BYTE - 1) (cnt_bit 7) !cnt_20_ns sck)flag_R_S 1b1 ;flag_b 1b0 ;endSEND : beginflag_b 1b0 ;flag_R_S 1b0 ;end default : beginflag_b 1b0 ;flag_R_S 1b0 ;end endcase end// reg flagBreg ;// reg flag_RSr ;always (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n)flagBreg 1b0 ;else flagBreg flag_b ;endalways (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n)flag_RSr 1b0 ;else flag_RSr flag_R_S ;end// reg [7:0] datInFifo ; // data_in_fifoalways (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) datInFifo 1b0 ;else if(flag_data)datInFifo {miso,datInFifo[7:1]}; // 读flash中数据先传的低位。else datInFifo datInFifo ;end// reg flag_data ; // flag_data 采样标志信号always (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n)flag_data 1b0 ;else if(state_c READ) beginif(cnt_20_ns !sck)flag_data 1b1 ;else flag_data 1b0 ;end else beginflag_data 1b0 ;endend// reg flaInFifo ; // flag_in_fifoalways (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n)flaInFifo 1b0 ;else if(state_c READ cnt_bit 7 flag_data)flaInFifo 1b1 ;else flaInFifo 1b0 ;end// reg [19:0] cnt_send ; // uart_tx模块发送1byte数据的等待时间。always (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) cnt_send 20d0 ;else if(state_c SEND) beginif(cnt_send CNT_MAX_SEND - 1) cnt_send 20d0 ;else cnt_send cnt_send 1b1 ;endelse cnt_send 20d0 ;end// reg flag_out_fifo_reg ;always (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n)flag_out_fifo_reg 1b0 ;else if(flaSenEnd !empty)flag_out_fifo_reg 1b1 ;else flag_out_fifo_reg 1b0 ;end// reg flaSenEnd ;always (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) flaSenEnd 1b0 ;else if(cnt_send CNT_MAX_SEND - 2)flaSenEnd 1b1 ;else flaSenEnd 1b0 ;end// output signal describe// cs_n ,always (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n)cs_n 1b1 ;else case (state_c)IDLE : if(key_flag)cs_n 1b0 ;else cs_n cs_n ;INSTRUCT: cs_n cs_n ;READ : cs_n cs_n ;SEND : cs_n 1b1 ;default : cs_n 1b1 ;endcaseend// sck ,always (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) sck 1b0 ;else case (state_c)IDLE : sck 1b0 ; INSTRUCT: if(cnt_20_ns)sck ~sck ;else sck sck ;READ : if(cnt_20_ns)sck ~sck ;else sck sck ;SEND : sck 1b0 ; default : sck 1b0 ; endcaseend// mosi ,always (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) beginmosi 1b0 ;end else begincase (state_c)IDLE : mosi 1b0 ;INSTRUCT: case (cnt_byte)0 : if(cnt_bit 0)mosi COMD_REA[7] ;else if(cnt_20_ns sck)mosi COMD_REA[7 - cnt_bit] ;else mosi mosi ;1 : if(cnt_bit 0)mosi ADDR_SEC[7] ;else if(cnt_20_ns sck)mosi ADDR_SEC[7 - cnt_bit] ;else mosi mosi ;2 : if(cnt_bit 0)mosi ADDR_PAG[7] ;else if(cnt_20_ns sck)mosi ADDR_PAG[7 - cnt_bit] ;else mosi mosi ;3 : if(cnt_bit 0)mosi ADDR_BYT[7] ;else if(cnt_20_ns sck)mosi ADDR_BYT[7 - cnt_bit] ;else mosi mosi ;default : mosi 1b0 ;endcaseREAD : mosi 1b0 ;SEND : mosi 1b0 ;default : mosi 1b0 ;endcaseendend// po_flag ,always (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n)po_flag 1b0 ;else po_flag flag_out_fifo_reg ;end// wire [7:0] po_data ;// 直接连接到fifo的输出端口。 // */
/***********************例化FIFO***************************************/assign flaOutFif flag_out_fifo_reg ;
fifo_1024x8 fifo_1024x8_inst(.clock ( sys_clk ) ,.data ( datInFifo ) ,.rdreq ( flaOutFif ) ,.wrreq ( flaInFifo ) ,.empty ( empty ) ,.full ( full ) ,.q ( po_data ) ,.usedw ( usedw )
);endmodule
module top (input wire sys_clk ,input wire sys_rst_n ,input wire key_in ,input wire miso ,output wire cs_n ,output wire sck ,output wire mosi ,output wire tx
);// 例化间连线wire key_flag ;wire po_flag ;wire [7:0] po_data ;key_filter key_filter_isnt(.sys_clk ( sys_clk ) ,.sys_rst_n ( sys_rst_n ) ,.key_in ( key_in ) ,.key_out ( key_flag )
);spi spi_inst(.sys_clk ( sys_clk ) ,.sys_rst_n ( sys_rst_n ) ,.key_flag ( key_flag ) ,.miso ( miso ) , .cs_n ( cs_n ) ,.sck ( sck ) ,.mosi ( mosi ) ,.po_flag ( po_flag ) ,.po_data ( po_data )
);uart_tx uart_tx_isnt(.sys_clk ( sys_clk ) ,.sys_rst_n ( sys_rst_n ) ,.pi_flag ( po_flag ) ,.pi_data ( po_data ) ,.tx ( tx )
);endmodule module key_filter
#(parameter MAX_CNT_20MS 20d100_0000
)(input wire sys_clk ,input wire sys_rst_n ,input wire key_in ,output wire key_out
);reg key_r_0 ;reg key_r_1 ;wire nege ;wire pose ;reg [19:00] cnt_20ms ;wire add_cnt_20ms ;wire end_cnt_20ms ;reg add_cnt_flag ;// key_r_0 key_r_1 always (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) beginkey_r_0 1b1 ;end else beginkey_r_0 key_in ;endendalways (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) beginkey_r_1 1b1 ;end else beginkey_r_1 key_r_0 ;endend// nege poseassign nege ~key_r_0 key_r_1 ;assign pose key_r_0 ~key_r_1 ;// add_cnt_flagalways (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) beginadd_cnt_flag 1b0 ;end else beginif(nege) beginadd_cnt_flag 1b1 ;end else beginif( pose || end_cnt_20ms ) beginadd_cnt_flag 1b0 ;end else beginadd_cnt_flag add_cnt_flag ;endend endend// cnt_20ms add_cnt_20ms end_cnt_20msalways (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) begincnt_20ms 20d0 ;end else beginif(add_cnt_20ms) beginif(end_cnt_20ms) begincnt_20ms 20d0 ;end else begincnt_20ms cnt_20ms 20d1 ;endend else begincnt_20ms 20d0 ;endendendassign add_cnt_20ms add_cnt_flag ;assign end_cnt_20ms add_cnt_20ms cnt_20ms ( MAX_CNT_20MS - 1b1 ) ;// key_out// always (posedge sys_clk or negedge sys_rst_n) begin// // always (*) begin // 这样的话 会综合成 数据选择器// if(~sys_rst_n) begin// key_out 1b0 ;// end else begin// if(end_cnt_20ms) begin// key_out 1b1 ;// end else begin// key_out 1b0 ;// end// end// endassign key_out end_cnt_20ms ;
endmodulemodule uart_tx (input wire sys_clk ,input wire sys_rst_n ,input wire pi_flag ,input wire [7:0] pi_data ,output reg tx
);// parameterparameter SUB_1K 1000 , // 缩减第十位空闲位的时间。CLK_UART 50_000_000 ,BPS 9600 ;localparam MAX_BPS CLK_UART / BPS ;// reg signal definereg pi_flag_reg1 ;reg [ 7:0] pi_data_reg1 ;reg work_en ;reg [12:0] cnt_bps ;reg [ 3:0] cnt_bit ;reg bit_flag ;/**********************************************/// reg pi_flag_reg1 ;always (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n)pi_flag_reg1 1b0 ;else pi_flag_reg1 pi_flag ;end// reg pi_data_reg1 ;always (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n)pi_data_reg1 8d0 ;else pi_data_reg1 pi_data ;end// reg work_en ;always (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) work_en 1b0 ;else if(((cnt_bit 4d0) pi_flag_reg1) || (cnt_bit 4d9) (bit_flag))work_en ~work_en ;else work_en work_en ;end// reg [12:0] cnt_bps ;always (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n)cnt_bps 13d0 ;else if(work_en cnt_bps MAX_BPS - 1) // 波特率计数器计数到最大值。cnt_bps 13d0 ;else if(work_en)cnt_bps cnt_bps 1b1 ;else cnt_bps 13d0 ;end// reg bit_flag ;always (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n)bit_flag 1b0 ;else if((work_en cnt_bps MAX_BPS - 1) || (work_en cnt_bps MAX_BPS - SUB_1K cnt_bit 9))bit_flag 1b1 ;else bit_flag 1b0 ;end// reg [ 3:0] cnt_bit ;always (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n)cnt_bit 4d0 ;else if(work_en bit_flag cnt_bit 4d9) // 传递完第十位位计数器要归零。cnt_bit 4d0 ;else if(work_en bit_flag)cnt_bit cnt_bit 1b1 ;else if(work_en)cnt_bit cnt_bit ;else cnt_bit 4d0 ;end/****************************************/// output signal// txalways (posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) tx 1b1 ;else if(work_en) begincase (cnt_bit)0 : tx 1b0 ;1 : tx pi_data_reg1[0] ; // 先发最低位。2 : tx pi_data_reg1[1] ;3 : tx pi_data_reg1[2] ;4 : tx pi_data_reg1[3] ;5 : tx pi_data_reg1[4] ;6 : tx pi_data_reg1[5] ;7 : tx pi_data_reg1[6] ;8 : tx pi_data_reg1[7] ;9 : tx 1b1 ;default: tx 1b1 ;endcase end else begintx 1b1 ;endend
endmodule timescale 1ns/1nsmodule test_spi();reg sys_clk ;reg sys_rst_n ;reg key_flag ;wire miso ;wire cs_n ;wire sck ;wire mosi ;wire po_flag ;wire [7:0] po_data ;defparam memory.mem_access.initfile initmemory.txt; defparam spi_inst.CNT_MAX_SEND 100 ;m25p16 memory (.c ( sck ) , .data_in ( mosi ) , .s ( cs_n ) , .w ( 1b1 ) , .hold ( 1b1 ) , .data_out ( miso )
);
spi spi_inst(.sys_clk ( sys_clk ) ,.sys_rst_n ( sys_rst_n ) ,.key_flag ( key_flag ) ,.miso ( miso ) ,.cs_n ( cs_n ) ,.sck ( sck ) ,.mosi ( mosi ) ,.po_flag ( po_flag ) ,.po_data ( po_data )
);parameter CYCLE 20 ;initial beginsys_clk 1b1 ;sys_rst_n 1b0 ;key_flag 1b0 ;#(CYCLE) ;sys_rst_n 1b1 ;#(CYCLE*10) ;#(CYCLE * 100) ;key_flag 1b1 ;#(CYCLE) ;key_flag 1b0 ;endalways #(CYCLE/2) sys_clk ~sys_clk ;endmodule 仿真波形 上版验证通过。