转至:https://blog.csdn.net/Headogerz/article/details/82346431
1.原理图,这次的协议是7*55/d5/aa(擦出flash)55(在flash中写入数据)。因此frame的控制模块至关重要。
2.仿真结果
这是仿真的frame控制模过滤协议之后产生的擦除地址与标志位,图中可以看出能够产生。
这是flash的擦除模块,这是flash模块中的扇区自动加一,这次擦除了8个扇区。
这是擦除完成的标志位,回传55表示擦除完成。
这是仿真在协议模块中过滤协议之后,产生写的地址、写地址标志位、写数据以及写数据的标志位。
通过观察flash的写控制模块可以发现flash可以写入相应的数据。
通过观察uart的tx模块端,结束标志位产生后,可以回传aa(16进制)
3.这次大综合需要用到的模块uart的rx模块和tx模块、flash的擦除模块和写入模块、按键消抖和icapIP核模块以及利用top模块将所有模块综合。
module rx_crtl( input wire sclk, input wire rst_n, input wire rx_in, output reg stop_flag, //新增数据监测停止位 output reg flag_o, output reg [7:0] data_o ); reg [12:0] cnt; reg [3:0] bit_cnt; reg rx_in_1,rx_in_2; reg rx_en; //使能信号值有问题 reg bit_flag; reg [7:0]tmp_data; reg tmp_flag; reg [16:0] cnt_clean; parameter CNT_CLEAN=100000;//28888; 仿真多写1个4 parameter CNT=5207; parameter BIT_CNT=8; parameter bit_flag_cnt=2603; // 产生bit采集标志位 //parameter clean_flag=2610; always@(posedge sclk or negedge rst_n) //ram输入信号清零计数器 if(!rst_n) cnt_clean<=16'd0; else if(flag_o==1'b1) // 少写了清零条件,导致写地址一直处于清零状态 cnt_clean<=16'd0; else if(cnt_clean==CNT_CLEAN) cnt_clean<=cnt_clean; // 优先级,当时产生清零标志位没有保持,而是清零导致产生无数个终端位 else if(flag_o==1'b0) //flag_o==1'b1,当时想的就是拉高开始计数,结果发现根本不计数 cnt_clean<=cnt_clean+1'b1; //因为标志位拉高只有一个时钟周期,应该记拉低的时钟周期。 always@(posedge sclk or negedge rst_n) //数据清零位传递给帧协议 if(!rst_n) stop_flag<=1'b0; else if (cnt_clean==CNT_CLEAN-1) stop_flag<=1'b1; else stop_flag<=1'b0; always@(posedge sclk or negedge rst_n) if(!rst_n) rx_in_1<=1'b1; else rx_in_1<=rx_in; always@(posedge sclk or negedge rst_n) //输入信号延时 if(!rst_n) rx_in_2<=1'b1; else rx_in_2<=rx_in_1; always@(posedge sclk or negedge rst_n) //产生计数使能信号 if(!rst_n) rx_en<=1'b0; else if(rx_in_1==1'b0&&rx_in_2==1'b1) rx_en<=1'b1; else if(bit_cnt==BIT_CNT&&cnt==CNT) rx_en<=1'b0; always@(posedge sclk or negedge rst_n) if(!rst_n) cnt<=13'd0; else if(rx_en==1'b0) cnt<=13'd0; else if(cnt==CNT) cnt<=13'd0; else if(rx_en==1'b1) cnt<=cnt+1'b1; always@(posedge sclk or negedge rst_n) //位宽计数 if(!rst_n) bit_cnt<=4'd0; else if(rx_en==1'b0) bit_cnt<=4'd0; else if(bit_cnt==BIT_CNT&&cnt==CNT) bit_cnt<=4'd0; else if(cnt==CNT) bit_cnt<=bit_cnt+1'b1; always@(posedge sclk or negedge rst_n) //产生bit标志位 if(!rst_n) bit_flag<=1'b0; else if(cnt==bit_flag_cnt) bit_flag<=1'b1; else bit_flag<=1'b0; always@(posedge sclk or negedge rst_n) //数据拼接 if(!rst_n) tmp_data<=8'd0; else if(bit_flag==1'b1&&bit_cnt>=4'd1&&bit_cnt<=4'd8) tmp_data<={rx_in_2,tmp_data[7:1]}; //少写分号 //else if(bit_cnt==BIT_CNT&&cnt==clean_flag) 数据不清零条件 // tmp_data<=8'd0; always@(posedge sclk or negedge rst_n) //数据拼接完成标志 if(!rst_n) tmp_flag<=1'b0; else if(bit_flag==1'b1&&bit_cnt==BIT_CNT) tmp_flag<=1'b1; else tmp_flag<=1'b0; always@(posedge sclk or negedge rst_n) if(!rst_n) data_o<=8'd0; else if(tmp_flag==1'b1) data_o<=tmp_data; always@(posedge sclk or negedge rst_n) if(!rst_n) flag_o<=1'b0; else flag_o<=tmp_flag; endmodule module w_farme( input wire sclk, input wire rst_n, input wire flag_uart, input wire [7:0] data_uart, input wire stop_flag, //数据发送完成标志 input wire sen_stop_flag, //擦除完成标识 output reg wr_flag, output reg [23:0] wr_addr, output reg [7:0] wr_data, output reg wr_flag_dizhi, output reg [23:0] se_addr, output reg se_flag, output reg tx_flag, output reg [7:0] tx_data //擦除结束用55标志,发生完成用aa标识 ); reg [10:0] state; parameter IDLE =11'b00000_0000_01; parameter H_1_55 =11'b00000_0000_10; parameter H_2_55 =11'b00000_0001_00; parameter H_3_55 =11'b00000_0010_00; parameter H_4_55 =11'b00000_0100_00; parameter H_5_55 =11'b00000_1000_00; parameter H_6_55 =11'b00001_0000_00; parameter H_7_55 =11'b00010_0000_00; parameter H_d5 =11'b00100_0000_00; parameter H_se =11'b01000_0000_00; parameter H_wr =11'b10000_0000_00; reg [2:0] cnt_flag; reg [23:0] tmp_addr; reg [2:0] cnt_flag_wr; reg [23:0] tmp_addr_wr; reg flag_uart_dely; reg flag_uart_dely1; always@(posedge sclk or negedge rst_n) if(!rst_n) state<=IDLE; //else if(stop_flag==1'b1) // state<=idle; else if(flag_uart==1'b1) case(state) IDLE : if(data_uart==8'h55) state<=H_1_55; else state<=IDLE; H_1_55: if(data_uart==8'h55) state<=H_2_55; else state<=IDLE; H_2_55: if(data_uart==8'h55) state<=H_3_55; else state<=IDLE; H_3_55: if(data_uart==8'h55) state<=H_4_55; else state<=IDLE; H_4_55: if(data_uart==8'h55) state<=H_5_55; else state<=IDLE; H_5_55: if(data_uart==8'h55) state<=H_6_55; else state<=IDLE; H_6_55: if(data_uart==8'h55) state<=H_7_55; else state<=IDLE; H_7_55: if(data_uart==8'hd5) state<=H_d5; else state<=IDLE; H_d5: if(data_uart==8'haa) state<=H_se; else if(data_uart==8'h55) state<=H_wr; else state<=IDLE; H_se: if(sen_stop_flag==1) state<=IDLE; else state<=state; H_wr: if(stop_flag==1) state<=IDLE; else state<=state; default:; endcase always@(posedge sclk or negedge rst_n) if(!rst_n) flag_uart_dely<=0; else flag_uart_dely<=flag_uart; always@(posedge sclk or negedge rst_n) if(!rst_n) flag_uart_dely1<=0; else flag_uart_dely1<=flag_uart_dely; always@(posedge sclk or negedge rst_n) //产生读计数器,对输入的标志位计数 if(!rst_n) cnt_flag<=2'd0; else if(sen_stop_flag==1) cnt_flag<=2'd0; else if(cnt_flag==5) cnt_flag<=cnt_flag; else if(state==H_se&&flag_uart_dely==1) cnt_flag<=cnt_flag+1; always@(posedge sclk or negedge rst_n) //读地址拼接——目前不确定要不要清零 if(!rst_n) tmp_addr<=24'd0; else if(state==H_se&&flag_uart==1&&cnt_flag<=3) tmp_addr<={tmp_addr[15:0],data_uart}; always@(posedge sclk or negedge rst_n) //地址发送 if(!rst_n) se_addr<=24'd0; else se_addr<=tmp_addr; always@(posedge sclk or negedge rst_n) //清除标志位产生 if(!rst_n) se_flag<=0; else if(cnt_flag==4) se_flag<=flag_uart_dely1; else se_flag<=0; always@(posedge sclk or negedge rst_n) //产生写计数器,对输入的标志位计数 if(!rst_n) cnt_flag_wr<=2'd0; else if(stop_flag==1) cnt_flag_wr<=2'd0; else if(cnt_flag_wr==5) cnt_flag_wr<=cnt_flag_wr; else if(state==H_wr&&flag_uart_dely==1) cnt_flag_wr<=cnt_flag_wr+1; always@(posedge sclk or negedge rst_n) //写地址拼接——目前不确定要不要清零wr_flag_dizhi if(!rst_n) tmp_addr_wr<=24'd0; else if(state==H_wr&&flag_uart==1&&cnt_flag_wr<=3) tmp_addr_wr<={tmp_addr_wr[15:0],data_uart}; always@(posedge sclk or negedge rst_n) //写地址拼接——目前不确定要不要清零wr_flag_dizhi if(!rst_n) wr_flag_dizhi<=0; else if(cnt_flag_wr==4) wr_flag_dizhi<=flag_uart_dely; else wr_flag_dizhi<=0; always@(posedge sclk or negedge rst_n) //地址发送 if(!rst_n) wr_addr<=24'd0; else wr_addr<=tmp_addr_wr; always@(posedge sclk or negedge rst_n) //数据发送标志位产生 if(!rst_n) wr_flag<=0; else if(cnt_flag_wr>=5) wr_flag<=flag_uart_dely1; else wr_flag<=0; always@(posedge sclk or negedge rst_n) //写的数据打拍 if(!rst_n) wr_data<=8'd0; else if(cnt_flag_wr==5) wr_data<=data_uart; else if(stop_flag==1) wr_data<=8'd0; always@(posedge sclk or negedge rst_n) //回传数据标志位 if(!rst_n) tx_flag<=0; else if(sen_stop_flag==1) tx_flag<=1; else if(stop_flag==1&&state==H_wr) tx_flag<=1; else tx_flag<=0; always@(posedge sclk or negedge rst_n) //回传数据 if(!rst_n) tx_data<=8'd0; else if(sen_stop_flag==1) tx_data<=8'h55; else if(stop_flag==1) tx_data<=8'haa; else tx_data<=8'd0; endmodule /*************************** spi协议控制flash扇区擦除 ****************************/ module flash_ctrl_se( input wire sclk, input wire rst_n, input wire pi_se_flag, input wire [23:0] se_addr_in, output reg led, output reg cs_n, output reg sck, output reg sdi, output reg sent_flag_out //地址清零结束位 ); reg [9:0] state; parameter idle =10'b0000_0000_01; parameter WAIT1 =10'b0000_0000_10; parameter WRITE =10'b0000_0001_00; parameter WAIT2 =10'b0000_0010_00; parameter WAIT3 =10'b0000_0100_00; parameter WAIT4 =10'b0000_1000_00; parameter SE =10'b0001_0000_00; parameter INIT_ADDR =10'b0010_0000_00; parameter WAIT5 =10'b0100_0000_00; parameter WAIT_3S =10'b1000_0000_00; reg [4:0] sclk_cnt; parameter SCLK_CNT=31; reg [1:0] cnt_init_addr; reg [25:0] cnt_1s; parameter ONE_S=49_9999_99; reg [1:0] cnt_3s; reg [1:0] cnt4; reg [2:0] bit_cnt; reg [3:0] cnt_wait_3s; reg [23:0] init_addr; parameter wr_en=8'h06; //信号差了一个时钟周期 parameter se_en=8'hd8; parameter CNT_wait_3s=7; reg cnt_3s_en; always@(posedge sclk or negedge rst_n) //循环擦除 if(!rst_n) cnt_wait_3s<=3'd0; else if(cnt_wait_3s==CNT_wait_3s&&cnt_1s==ONE_S&&cnt_3s==2) cnt_wait_3s<=3'd0; else if(state==WAIT_3S&&cnt_1s==ONE_S&&cnt_3s==2) cnt_wait_3s<=cnt_wait_3s+1'b1; always@(posedge sclk or negedge rst_n) //扇区地址变换 if(!rst_n) init_addr<=24'd0; else if(pi_se_flag==1) init_addr<=se_addr_in; else if(state==WAIT_3S&&cnt_1s==ONE_S&&cnt_3s==2) / init_addr<=init_addr+24'h01_0000; else if(state==idle) init_addr<=24'd0; always@(posedge sclk or negedge rst_n) //为输出时钟计数 if(!rst_n) cnt4<=2'd0; else if(cnt4==3) cnt4<=2'd0; else if(state==WRITE||state==SE||state==INIT_ADDR) cnt4<=cnt4+1; always@(posedge sclk or negedge rst_n) // bit位计数 if(!rst_n) bit_cnt<=3'd0; else if(bit_cnt==7&&cnt4==3) bit_cnt<=3'd0; else if(cnt4==3) bit_cnt<=bit_cnt+1; always@(posedge sclk or negedge rst_n) if(!rst_n) cnt_1s<=26'd0; else if(cnt_1s==ONE_S) cnt_1s<=26'd0; else if(cnt_3s_en==1) cnt_1s<=cnt_1s+1; always@(posedge sclk or negedge rst_n) if(!rst_n) cnt_3s<=2'd0; else if(cnt_1s==ONE_S&&cnt_3s==2) cnt_3s<=2'd0; else if(cnt_1s==ONE_S) cnt_3s<=cnt_3s+1; always@(posedge sclk or negedge rst_n) //3秒使能信号 if(!rst_n) cnt_3s_en<=0; else if(cnt_1s==ONE_S&&cnt_3s==2) cnt_3s_en<=0; else if(state==WAIT_3S) cnt_3s_en<=1; always@(posedge sclk or negedge rst_n) if(!rst_n) cs_n<=1; else if(pi_se_flag==1) cs_n<=0; else if(state==idle) cs_n<=1; else if(state==WAIT2&&sclk_cnt==SCLK_CNT) //片选信号没有描述对 cs_n<=1; else if(state==WAIT3&&sclk_cnt==SCLK_CNT) cs_n<=0; else if(state==WAIT5&&sclk_cnt==SCLK_CNT) cs_n<=1; else if(state==WAIT_3S&&cnt_1s==ONE_S&&cnt_3s==2) cs_n<=0; //else if(cnt_wait_3s==CNT_wait_3s) //cs_n<=1; always@(posedge sclk or negedge rst_n) if(!rst_n) sclk_cnt<=5'd0; else if (sclk_cnt==SCLK_CNT&&cnt_wait_3s==CNT_wait_3s) sclk_cnt<=5'd0; else if(sclk_cnt==SCLK_CNT) sclk_cnt<=5'd0; else if(cs_n==0) sclk_cnt<=sclk_cnt+1; else if(state==WAIT3) sclk_cnt<=sclk_cnt+1; always@(posedge sclk or negedge rst_n) //3位状态计数 if(!rst_n) cnt_init_addr<=2'd0; else if(cnt_init_addr==2'd2&&sclk_cnt==SCLK_CNT) cnt_init_addr<=2'd0; else if(sclk_cnt==SCLK_CNT&&state==INIT_ADDR) cnt_init_addr<=cnt_init_addr+1; always@(posedge sclk or negedge rst_n) if(!rst_n) state<=idle; else case(state) idle: if(pi_se_flag==1) state<=WAIT1; else state<=idle; WAIT1: if(sclk_cnt==SCLK_CNT) state<=WRITE; else state<=WAIT1; WRITE: if(sclk_cnt==SCLK_CNT) state<=WAIT2; else state<=WRITE; WAIT2: if(sclk_cnt==SCLK_CNT) state<=WAIT3; else state<=WAIT2; WAIT3: if(sclk_cnt==SCLK_CNT) state<=WAIT4; else state<=WAIT3; WAIT4: if(sclk_cnt==SCLK_CNT) state<=SE; SE: if(sclk_cnt==SCLK_CNT) state<=INIT_ADDR; else state<=SE; INIT_ADDR: if(cnt_init_addr==2'd2&&sclk_cnt==SCLK_CNT) state<=WAIT5; else state<=INIT_ADDR; WAIT5: if(sclk_cnt==SCLK_CNT) state<=WAIT_3S; else state<=WAIT5; WAIT_3S: if(cnt_1s==ONE_S&&cnt_3s==2) state<=WAIT1; else if(cnt_wait_3s==CNT_wait_3s) state<=idle; default: state<=idle; endcase always@(posedge sclk or negedge rst_n) //时钟传递 if(!rst_n) sck<=0; else if(state==WRITE &&cnt4==1) sck<=1; else if(state==WRITE&&cnt4==3) sck<=0; else if (state==SE&&cnt4==1) sck<=1; else if(state==SE&&cnt4==3) sck<=0; else if (state==INIT_ADDR&&cnt4==1) sck<=1; else if(state==INIT_ADDR&&cnt4==3) sck<=0; always@(posedge sclk or negedge rst_n) //低电平传输数据 上升沿采集数据 if(!rst_n) sdi<=1'b1; else if(state==WRITE) sdi<=wr_en[7-bit_cnt]; else if(state==SE) sdi<=se_en[7-bit_cnt]; else if(state==INIT_ADDR&&cnt_init_addr==0) sdi<=init_addr[23-bit_cnt]; else if(state==INIT_ADDR&&cnt_init_addr==1) sdi<=init_addr[15-bit_cnt]; else if(state==INIT_ADDR&&cnt_init_addr==2) sdi<=init_addr[7-bit_cnt]; else sdi<=1'b1; //检查发现有问题 always@(posedge sclk or negedge rst_n) if(!rst_n) led<=0; else if(cnt_3s_en==1) led<=1; else led<=0; always@(posedge sclk or negedge rst_n) if(!rst_n) sent_flag_out<=0; else if(cnt_wait_3s==CNT_wait_3s&&cnt_1s==ONE_S&&cnt_3s==2) sent_flag_out<=1; else sent_flag_out<=0; endmodule /*************************** spi协议控制flash扇区数据输入 ****************************/ module flash_ctrl_wr( input wire sclk, input wire rst_n, input wire pi_flag, input wire pi_flag_dizhi, input wire [7:0] data_in, input wire stop_flag_rx, //发送端输入的停止位 input wire [23:0] frame_wr_addr, output reg cs_n, output reg sck, output reg sdi ); reg [9:0] state; parameter idle =10'b0000_0000_01; parameter WAIT1 =10'b0000_0000_10; parameter WRITE =10'b0000_0001_00; parameter WAIT2 =10'b0000_0010_00; parameter WAIT3 =10'b0000_0100_00; parameter WAIT4 =10'b0000_1000_00; parameter PP =10'b0001_0000_00; parameter INIT_ADDR =10'b0010_0000_00; parameter DATA_IN =10'b0100_0000_00; parameter WAIT5 =10'b1000_0000_00; reg [4:0] sclk_cnt; parameter SCLK_CNT=31; reg [1:0] cnt_init_addr; reg [1:0] cnt4; reg [2:0] bit_cnt; reg add_addr_flag; reg [23:0] init_addr; parameter INIT_ADDR_Location=6'h00_00_00; parameter wr_en=8'h06; parameter PP_en=8'h02; always@(posedge sclk or negedge rst_n) if(!rst_n) add_addr_flag<=0; else if(state==WAIT5&&sclk_cnt==SCLK_CNT) add_addr_flag<=1; else add_addr_flag<=0; always@(posedge sclk or negedge rst_n) if(!rst_n) init_addr<=INIT_ADDR_Location; else if(pi_flag_dizhi==1) init_addr<=frame_wr_addr; else if(add_addr_flag==1) init_addr<=init_addr+24'h0000_01; //字节自动加一,加到255后页自动加一 //else init_addr<=24'd0; always@(posedge sclk or negedge rst_n) if(!rst_n) cnt4<=2'd0; else if(cnt4==3) cnt4<=2'd0; else if(state==WRITE||state==PP||state==INIT_ADDR||state==DATA_IN) cnt4<=cnt4+1; always@(posedge sclk or negedge rst_n) if(!rst_n) bit_cnt<=3'd0; else if(bit_cnt==7&&cnt4==3) bit_cnt<=3'd0; else if(cnt4==3) bit_cnt<=bit_cnt+1; always@(posedge sclk or negedge rst_n) if(!rst_n) cs_n<=1; else if(pi_flag==1) cs_n<=0; else if(state==WAIT2&&sclk_cnt==SCLK_CNT) cs_n<=1; else if(state==WAIT3&&sclk_cnt==SCLK_CNT) cs_n<=0; else if(sclk_cnt==SCLK_CNT&&state==WAIT5) cs_n<=1; always@(posedge sclk or negedge rst_n) if(!rst_n) sclk_cnt<=5'd0; else if (sclk_cnt==SCLK_CNT&&state==WAIT5) sclk_cnt<=5'd0; else if(sclk_cnt==SCLK_CNT) sclk_cnt<=5'd0; else if(cs_n==0) sclk_cnt<=sclk_cnt+1; else if(state==WAIT3) sclk_cnt<=sclk_cnt+1; always@(posedge sclk or negedge rst_n) if(!rst_n) cnt_init_addr<=2'd0; else if(cnt_init_addr==2'd2&&sclk_cnt==SCLK_CNT) cnt_init_addr<=2'd0; else if(sclk_cnt==SCLK_CNT&&state==INIT_ADDR) cnt_init_addr<=cnt_init_addr+1; always@(posedge sclk or negedge rst_n) if(!rst_n) state<=idle; else case(state) idle: if(pi_flag==1) state<=WAIT1; else state<=idle; WAIT1: if(sclk_cnt==SCLK_CNT) state<=WRITE; else state<=WAIT1; WRITE: if(sclk_cnt==SCLK_CNT) state<=WAIT2; else state<=WRITE; WAIT2: if(sclk_cnt==SCLK_CNT) state<=WAIT3; else state<=WAIT2; WAIT3: if(sclk_cnt==SCLK_CNT) state<=WAIT4; else state<=WAIT3; WAIT4: if(sclk_cnt==SCLK_CNT) state<=PP; PP: if(sclk_cnt==SCLK_CNT) state<=INIT_ADDR; else state<=PP; INIT_ADDR: if(cnt_init_addr==2'd2&&sclk_cnt==SCLK_CNT) state<=DATA_IN; else state<=INIT_ADDR; DATA_IN: if(sclk_cnt==SCLK_CNT) state<=WAIT5; else state<=DATA_IN; WAIT5: if(stop_flag_rx) state<=idle; else if(sclk_cnt==SCLK_CNT) state<=idle; else state<=WAIT5; default: state<=idle; endcase always@(posedge sclk or negedge rst_n) //时钟传递 if(!rst_n) sck<=0; else if(state==WRITE &&cnt4==1) sck<=1; else if(state==WRITE&&cnt4==3) sck<=0; else if (state==PP&&cnt4==1) sck<=1; else if(state==PP&&cnt4==3) sck<=0; else if (state==INIT_ADDR&&cnt4==1) sck<=1; else if(state==INIT_ADDR&&cnt4==3) sck<=0; else if (state==DATA_IN&&cnt4==1) sck<=1; else if(state==DATA_IN&&cnt4==3) sck<=0; always@(posedge sclk or negedge rst_n) if(!rst_n) sdi<=1'b1; else if(state==WRITE) sdi<=wr_en[7-bit_cnt]; else if(state==PP) sdi<=PP_en[7-bit_cnt]; else if(state==INIT_ADDR&&cnt_init_addr==0) sdi<=init_addr[23-bit_cnt]; else if(state==INIT_ADDR&&cnt_init_addr==1) sdi<=init_addr[15-bit_cnt]; else if(state==INIT_ADDR&&cnt_init_addr==2) sdi<=init_addr[7-bit_cnt]; else if(state==DATA_IN) sdi<=data_in[7-bit_cnt]; else sdi<=1'b1; endmodule module key_rock( input wire sclk, input wire rst_n, input wire key_in, output reg key_o ); reg [18:0] cnt; parameter CNT_MAX=500000-1; always@(posedge sclk or negedge rst_n) if(!rst_n) cnt<=1'b0; else if(key_in==1) cnt<=0; else if(cnt==CNT_MAX) cnt<=cnt; else cnt<=cnt+1'b1; always@(posedge sclk or negedge rst_n) if(!rst_n) key_o<=1'b0; else if (cnt==CNT_MAX-1) key_o<=1'b1; else key_o<=1'b0; endmodule module icap_ctrl( input wire sclk, input wire rst_n, input wire key_in, input wire [23:0] wr_addr_frame ); reg [3:0] cnt; reg ce; reg [15:0] tmp_i; wire [15:0] i_data; always@(posedge sclk or negedge rst_n) //cnt14 if(!rst_n) cnt<=4'd0; else if(cnt==14) cnt<=4'd0; else if (ce==0) cnt<=cnt+1'b1; always@(posedge sclk or negedge rst_n) //ce if(!rst_n) ce<=1'b1; else if(cnt==14) ce<=1'b1; else if (key_in==1) //不是很理解 ce<=1'b0; always@(posedge sclk or negedge rst_n) if(!rst_n) tmp_i<=16'hffff; else case(cnt) 0: tmp_i<=16'hffff; 1: tmp_i<=16'haa99; 2: tmp_i<=16'h5566; 3: tmp_i<=16'h3261; 4: tmp_i<=wr_addr_frame[15:0]; //{data_uart,tmp_addr[7:0]}; 5: tmp_i<=16'h3281; 6: tmp_i<={8'h03,wr_addr_frame[23:16]};// 7: tmp_i<=16'h32a1; 8: tmp_i<=16'h0000; // 9: tmp_i<=16'h32c1; 10: tmp_i<=16'h0300; // 11: tmp_i<=16'h30a1; 12: tmp_i<=16'h000e; 13: tmp_i<=16'h2000; 14: tmp_i<=16'hffff; default: tmp_i<=16'hffff; endcase assign i_data={tmp_i[8],tmp_i[9],tmp_i[10],tmp_i[11],tmp_i[12],tmp_i[13],tmp_i[14],tmp_i[15], tmp_i[0],tmp_i[1],tmp_i[2],tmp_i[3],tmp_i[4],tmp_i[5],tmp_i[6],tmp_i[7]}; ICAP_SPARTAN6 #( .DEVICE_ID(28'h4000093), // Specifies the pre-programmed Device ID value .SIM_CFG_FILE_NAME("NONE") // Specifies the Raw Bitstream (RBT) file to be parsed by the simulation // model ) ICAP_SPARTAN6_inst ( .BUSY(), // 1-bit output: Busy/Ready output .O(), // 16-bit output: Configuartion data output bus .CE(ce), // 1-bit input: Active-Low ICAP Enable input .CLK(sclk), // 1-bit input: Clock input .I(i_data), // 16-bit input: Configuration data input bus .WRITE(1'b0) // 1-bit input: Read/Write control input ); endmodule module tx_crtl( input wire sclk, input wire rst_n, input wire [7:0] data_in, input wire flag_in, output reg data_o ); reg [12:0] cnt; reg [3:0] bit_cnt; reg tx_en; parameter CNT=5207; parameter BIT_CNT=8; reg [7:0] data_in_dely; always@(posedge sclk or negedge rst_n) if(!rst_n) data_in_dely<=8'd0; else if(flag_in==1) data_in_dely<=data_in; else if(tx_en==0) data_in_dely<=8'd0; //tx_en always@(posedge sclk or negedge rst_n) if(!rst_n) tx_en<=1'b0; else if(flag_in==1'b1) tx_en<=1'b1; else if(bit_cnt==BIT_CNT&&cnt==CNT) tx_en<=1'b0; //cnt 波特率计数 always@(posedge sclk or negedge rst_n) if(!rst_n) cnt<=13'd0; else if(cnt==CNT) cnt<=13'd0; else if(tx_en==1'b1) //条件没写对 cnt<=cnt+1'b1; //bit_cnt 字节统计 always@(posedge sclk or negedge rst_n) if(!rst_n) bit_cnt<=4'd0; else if(tx_en==1'b0) bit_cnt<=4'd0; else if(bit_cnt==BIT_CNT&cnt==CNT) bit_cnt<=4'd0; else if(cnt==CNT) bit_cnt<=bit_cnt+1'b1; //输出数据控制 always@(posedge sclk or negedge rst_n) if(!rst_n) data_o<=1'b1; else if(tx_en==1'b0) //flag_in==1'b1 data_o<=1'b1; else if(bit_cnt==10'd0) //flag_in==1'b1 data_o<=1'b0; else if(bit_cnt==10'd1) data_o<=data_in_dely[0]; else if (bit_cnt==10'd2) data_o<=data_in_dely[1]; else if(bit_cnt==10'd3) data_o<=data_in_dely[2]; else if(bit_cnt==10'd4) data_o<=data_in_dely[3]; else if(bit_cnt==10'd5) data_o<=data_in_dely[4]; else if(bit_cnt==10'd6) data_o<=data_in_dely[5]; else if(bit_cnt==10'd7) data_o<=data_in_dely[6]; else if(bit_cnt==10'd8) data_o<=data_in_dely[7]; //else if(bit_cnt==BIT_CNT) // data_o<=1'b1; else data_o<=1'b1; endmodule module top_updata( input wire sclk, input wire rst_n, input wire rx_uart_data, input wire key_in, output wire tx_data, output wire led, output wire cs_n, output wire sck, output wire sdi ); wire key_inst_o; wire stop_flag_rx; wire flag_o_rx; wire [7:0] data_o_rx; wire wr_flag_frame_inst; wire [23:0] wr_addr_frame_inst; wire [7:0] wr_data_inst; wire se_flag_frame; wire [23:0] se_addr_frame; wire sent_flag_out_se_inst; wire tx_flag_frame; wire [7:0] tx_data_farme; wire wr_inst_cs_n; wire wr_inst_sck; wire wr_inst_sdi; wire se_inst_cs_n; wire se_inst_sck; wire se_inst_sdi; wire wr_flag_dizhi; assign cs_n=(wr_inst_cs_n&&se_inst_cs_n); assign sck=(wr_inst_sck||se_inst_sck); assign sdi=(wr_inst_sdi&&se_inst_sdi); key_rock key_rock_inst( .sclk (sclk), .rst_n (rst_n), .key_in (key_in), .key_o (key_inst_o) ); icap_ctrl icap_ctrl_inst( .sclk (sclk), .rst_n (rst_n), .key_in (key_inst_o), .wr_addr_frame (wr_addr_frame_inst) ); rx_crtl rx_crtl_inst( .sclk (sclk), .rst_n (rst_n), .rx_in (rx_uart_data), .stop_flag (stop_flag_rx), .flag_o (flag_o_rx), .data_o (data_o_rx) ); w_farme w_farme_inst( .sclk (sclk), .rst_n (rst_n), .flag_uart (flag_o_rx), .data_uart (data_o_rx), .stop_flag (stop_flag_rx), //数据发送完成标志 .sen_stop_flag (sent_flag_out_se_inst), //擦除完成标识 .wr_flag_dizhi (wr_flag_dizhi), .wr_flag (wr_flag_frame_inst), .wr_addr (wr_addr_frame_inst), .wr_data (wr_data_inst), .se_addr (se_addr_frame), .se_flag (se_flag_frame), .tx_flag (tx_flag_frame), .tx_data (tx_data_farme) //擦除结束用55标志,发生完成用aa标识 ); flash_ctrl_wr flash_ctrl_wr_inst( .sclk (sclk), .rst_n (rst_n), .pi_flag (wr_flag_frame_inst), .data_in (wr_data_inst), .stop_flag_rx (stop_flag_rx), //发送端输入的停止位 .frame_wr_addr (wr_addr_frame_inst), .pi_flag_dizhi (wr_flag_dizhi), .cs_n (wr_inst_cs_n), .sck (wr_inst_sck), .sdi (wr_inst_sdi) ); flash_ctrl_se flash_ctrl_se_inst( .sclk (sclk), .rst_n (rst_n), .pi_se_flag (se_flag_frame), .se_addr_in (se_addr_frame), .led (led), .cs_n (se_inst_cs_n), .sck (se_inst_sck), .sdi (se_inst_sdi), .sent_flag_out (sent_flag_out_se_inst) //地址清零结束位 ); tx_crtl tx_crtl_inst( .sclk (sclk), .rst_n (rst_n), .data_in (tx_data_farme), .flag_in (tx_flag_frame), .data_o (tx_data) ); endmodule `timescale 1ns/1ns module tb_update; reg sclk; reg rst_n; reg rx; reg[7:0] a_mem[18:0]; //当前为测试flash写模块 擦出数据为55 55 55 55 55 55 55 d5 aa 10 00 00 initial $readmemh("./data.txt", a_mem); //测试flash写入数据为55 55 55 55 55 55 55 d5 55 10 00 00 01 02 03 04 05 aa 55 initial begin sclk = 1'b1; rst_n <= 1'b0; #300 rst_n <= 1'b1; end always #10 sclk = ~sclk; initial begin rx <= 1'b1; #2000 rx_byte(); end task rx_byte(); integer j;//定义一个整型变量 for(j=0;j<19;j=j+1)//for循环 测试的时候,数据加到原来的256应该是86 rx_bit(a_mem[j]);//a_mem[j]是data.txt文件里面第j个8比特数据 //j每次取一个值,就调用一次rx_bit(); //一共调用256次 endtask task rx_bit(input [7:0] data);//data是a_mem[j]的值。 integer i; for(i=0;i<10;i=i+1) begin case(i) 0: rx <= 1'b0;//起始位 1: rx <= data[0]; 2: rx <= data[1]; 3: rx <= data[2]; 4: rx <= data[3]; 5: rx <= data[4]; 6: rx <= data[5]; 7: rx <= data[6]; 8: rx <= data[7]; //上面8个发送的是数据位 9: rx <= 1'b1;//停止位 endcase #104140;//一个波特时间=sclk周期*波特计数器 end endtask defparam top_updata_inst.flash_ctrl_se_inst.ONE_S=500; //defparam top_updata_inst.rx_crtl_inst.CNT=9; //defparam top_updata_inst.rx_crtl_inst.bit_flag_cnt=4; //defparam top_updata_inst.tx_crtl_inst.CNT=10; top_updata top_updata_inst( .sclk (sclk), .rst_n (rst_n), .rx_uart_data (rx), .key_in () ); endmodule4.这次比较难调试的frame_ctrl模块,多次仿真最终达到目的
5.如果仿真通过,下载只办卡却没有达到应有效果,就需要利用ise的chipscope对内部信号进行抓取。
6.擦除调试如图: