银杏科技有限公司旗下技术文档发布平台 | |||
技术支持电话 | 0379-69926675-801 | ||
技术支持邮件 | Gingko@vip.163.com | ||
版本 | 日期 | 作者 | 修改内容 |
---|---|---|---|
V1.0 | 2020-07-01 | gingko | 初次建立 |
1、新建一个工程名为spram的工程,然后在工程目录选中工程,右键单击,下来菜单中点击New Source …。 2、弹出界面中选中IP(CORE Generator & Architecture Wizard)选项,并在右侧File name栏输入新建IP核的文件名,然后点击Next。 3、在Select IP界面的Memories & Storage Elements 栏下找到RAM & ROM,点击前面的“+”展开,单击选中Block Memory Generator,点击Next 进入下一步。 4、直接点击Finished。 5、然后弹出RAM IP 核相关信息设置的界面,这里的Interface Type选项保持默认设置Native即可,然后点击Next,如下图所示: 6、在Memory Type 栏选择RAM类型,本实验是单口RAM实验,所以这里选择Single Port RAM,然后点击Next。 7、设置单口RAM的位宽参数为8位,存储深度为1024,Operating Mode和Enable下勾选如下选项,如图中所示;然后点击Next。 8、此界面配置RAM初始化内容,本实验不需要初始化RAM数据,保持默认即可,直接点击Next。 9、接下来默认设置,点击Next。 10、点击Generate,完成单口RAM IP核的添加。 11、回到工程界面,可以看到工程目录中多了RAM IP核文件。
//------------------------------------------------// //spi_ram //负责存储SPI通信的数据(具体的存储位置可通过spi命令寄存器设置) //单口RAM的缺点在于只有一套数据线和地址线、一个时钟信号,需要分时复用。 //有点在于相同容量的RAM占用的逻辑资源小于双口RAM。 spi_ram u0( .clock(clk), .wren(wr_en), .address(address), .data(receive_byte), .rden(rd_en), .q(data_out) );
case(rx_state) rx_idle_state:begin//空闲状态,匹配伪命令时钟 rx_state <= rx_judge_state; end rx_judge_state:begin//接收指令字节,判断指令含义分配跳转状态机状态 case(receive_byte) 8'h01:begin//存储指令编码(获取设备状态) order <= receive_byte; end 8'h02:begin//存储指令编码,跳转状态(写数据的长度信息) rx_state <= rx_wr_length_state; order <= receive_byte; end 8'h04:begin//存储指令编码,跳转状态(写数据的地址信息) rx_state <= rx_wr_add_state; order <= receive_byte; end 8'h05:begin//存储指令编码,跳转状态(读数据的长度信息) rx_state <= rx_rd_ledgth_state; order <= receive_byte; end 8'h07:begin//存储指令编码,跳转状态(读数据的地址信息) rx_state <= rx_rd_add_state; order <= receive_byte; end default:; endcase end rx_wr_length_state:begin//获取写数据长度信息,高字节在前,低字节在后 case(rx_cnt) 8'd0:begin wr_length_r[15:8] <= receive_byte; rx_cnt <= rx_cnt + 1'd1; end 8'd1:begin wr_length_r <= {wr_length_r[15:8],receive_byte}; end default:begin end endcase end rx_wr_add_state:begin//获取写数据地址,高字节在前,并产生RAM的写地址信息 case(rx_cnt) 8'd0:begin wr_address_r[15:8] <= receive_byte; rx_cnt <= rx_cnt + 1'd1; end 8'd1:begin wr_address_r <= {wr_address_r[15:8],receive_byte}; rx_cnt <= rx_cnt + 1'd1; wr_en_r <= 1'd1; end 8'd2:begin wr_address_r <= wr_address_r + 1'd1; if(wr_cnt==wr_length_r-1'd1) begin wr_cnt <= 12'h00; rx_cnt <= rx_cnt + 1'd1; end else begin wr_cnt <= wr_cnt + 1'd1; end end default:begin end endcase end rx_rd_ledgth_state:begin//获取读数据长度信息,高字节在前,低字节在后 case(rx_cnt) 8'd0:begin rd_length_r[15:8] <= receive_byte; rx_cnt <= rx_cnt + 1'd1; end 8'd1:begin rd_length_r <= {rd_length_r[15:8],receive_byte}; end default:begin end endcase end rx_rd_add_state:begin//获取读数据地址信息,高字节在前,并产生RAM的读地址信息 case(rx_cnt) 8'd0:begin rd_address_r[15:8] <= receive_byte; rx_cnt <= rx_cnt + 1'd1; end 8'd1:begin rd_address_r <= {rd_address_r[15:8],receive_byte}; rx_cnt <= rx_cnt + 1'd1; rd_en_r <= 1'd1; end 8'd2:begin rd_address_r <= rd_address_r + 1'd1; if(rd_cnt==rd_length_r-1'd1) begin rd_cnt <= 12'h00; rx_cnt <= rx_cnt + 1'd1; end else begin rd_cnt <= rd_cnt + 1'd1; end end default:; endcase end