博客
关于我
SPI主机的Verilog代码及验证(优化版)
阅读量:358 次
发布时间:2019-03-04

本文共 4022 字,大约阅读时间需要 13 分钟。

这次重新写了一遍初学FPGA时写的SPI主机驱动,减少了代码量,舍弃了状态机,补充了同时发送和接受功能的验证

代码

//Module Name:SPI Master//Author:Yang Cheng Yu//Date:2020/4/20`define SIMmodule	spi_master(	//system signal	input				clk,	input				rst_n,	//spi_master interface	output	reg			sclk,	output	reg			mosi,	input				miso,	input	[7:0]		data_tx,	output	reg	[7:0]	data_rx,	//others	input				tx_req,	output  reg 		flag_work,	output				cs);//parameter and defines	localparam			SYS_FRE = 50_000_000;	`ifndef				SIM	localparam			SCLK_FRE = 1000;	localparam			BAUD_CNT_END = SYS_FRE/SCLK_FRE-1;	localparam			BAUD_CNT_HALF = SYS_FRE/SCLK_FRE/2-1;	`else	localparam			BAUD_CNT_END = 499;	localparam			BAUD_CNT_HALF = 249;	`endif//	localparam	BAUD_CNT_1_half2 = SYS_FRE/SCLK_FRE/4-1;//system regs	reg[7:0]			data_tx_reg;	reg[15:0]			cnt_baud;	reg[2:0]			cnt_bit;	reg 				tx_req_t0;	reg 				tx_req_t1;	wire 				trig_tx_req;	wire 				flag_bit;	reg[7:0]			data_rx_reg;//main_code	//trig_tx_req	always	@(posedge clk)begin		tx_req_t0 <= tx_req;		tx_req_t1 <= tx_req_t0;	end	assign	trig_tx_req = tx_req_t0&(~tx_req_t1);	//sclk	always	@(posedge clk or negedge rst_n)begin		if(rst_n==1'b0)			sclk <= 1'b0;		else if(cnt_baud==BAUD_CNT_HALF)			sclk <= 1'b1;		else if(cnt_baud==BAUD_CNT_END)			sclk <= 1'b0;	end	//data_tx_reg	always	@(posedge clk or negedge rst_n)begin		if(rst_n==1'b0)			data_tx_reg <= 'd0;		else if(trig_tx_req==1'b1&&flag_work==1'b0)			data_tx_reg <= data_tx;	end	//cnt_baud	always	@(posedge clk or negedge rst_n)begin		if(rst_n==1'b0)			cnt_baud <= 'd0;		else if(flag_work==1'b1)			if(cnt_baud==BAUD_CNT_END)				cnt_baud <= 'd0;			else				cnt_baud <= cnt_baud + 1'b1;		else			cnt_baud <= 'd0;	end	//cnt_bit	always	@(posedge clk or negedge rst_n)begin		if(rst_n==1'b0)			cnt_bit <= 'd0;		else if(flag_bit==1'b1&&cnt_bit==3'd7)			cnt_bit <= 'd0;		else if(flag_bit==1'b1)			cnt_bit <= cnt_bit + 1'b1;	end	//mosi	always	@(posedge clk or negedge rst_n)begin		if(rst_n==1'b0)			mosi <= 1'b0;		else if(cnt_baud==BAUD_CNT_HALF)			mosi <= data_tx_reg[7-cnt_bit];	end	//flag_work	always	@(posedge clk or negedge rst_n)begin		if(rst_n==1'b0)			flag_work <= 1'b0;		else if(flag_work==1'b0&&trig_tx_req==1'b1)			flag_work <= 1'b1;		else if(flag_work==1'b1&&cnt_bit==3'd7&&flag_bit==1'b1)			flag_work <= 1'b0;	end	//flag_bit	assign	flag_bit = (cnt_baud==BAUD_CNT_END)?1'b1:1'b0;	//data_rx_reg	always	@(posedge clk or negedge rst_n)begin		if(rst_n==1'b0)			data_rx_reg <= 'd0;		else if(flag_work==1'b1)			if(cnt_baud==BAUD_CNT_HALF)				data_rx_reg <= {   data_rx_reg[6:0],miso};	end	//data_rx	always	@(posedge clk or negedge rst_n)begin		if(rst_n==1'b0)			data_rx <= 'd0;		else if(cnt_bit==7&&flag_bit==1'b1)			data_rx <= data_rx_reg;	end	//cs	assign cs = ~flag_work;	endmodule

Test Bench

`timescale	1ns/1ns		//时间精度`define clock_period 20	//时钟周期module tb_spi_master;	//实体名称//=====================
<系统端口>
=============================reg clk;reg rst_n;//=====================
<外设端口>
=============================wire sclk;wire mosi;reg miso;reg [7:0] data_tx;wire[7:0] data_rx;reg tx_req;wire flag_work;wire cs;integer i;reg[7:0] data;spi_master spi_master_inst( //system signal .clk (clk), .rst_n (rst_n), //spi_master interface .sclk (sclk), .mosi (mosi), .miso (miso), .data_tx (data_tx), .data_rx (data_rx), //others .tx_req (tx_req), .flag_work (flag_work), .cs (cs));//=====================
<时钟信号>
=============================initial begin clk = 1; forever #(`clock_period/2) clk = ~clk;end//=====================
<复位信号>
=============================initial begin rst_n = 0;#(`clock_period*20+1); rst_n = 1;end//=====================
<激励信号>
=============================initial begin data_tx = 8'h00; tx_req = 1'b0; #(`clock_period*20+1);//初始化 data_tx = 8'h56; #100; tx_req = 1'b1; #20; tx_req = 1'b0;end initial begin miso = 0; data = 8'h00; #(`clock_period*20+1);//初始化 #100; data = 8'h37; for(i=0;i<7;i=i+1)begin miso = data[7-i]; #(`clock_period*500); endendendmodule

仿真模拟发送0x56,接收0x37数据。波形正确

仿真时序图

在这里插入图片描述

转载地址:http://nvug.baihongyu.com/

你可能感兴趣的文章
Android wm命令
查看>>
boot.img 解包与打包
查看>>
Android4.4 平板背光设置
查看>>
递归复习--二叉搜索树
查看>>
jvm-02
查看>>
spring boot@Value和bean执行顺序问题
查看>>
从浏览器输入网址到服务器返回经历的过程
查看>>
解决Genymotion无法拖拽的问题
查看>>
中国石油大学《计算机文化基础》在线考试(客观题)
查看>>
强化学习(8):Asynchronous Advantage Actor-Critic(A3C)算法
查看>>
中国石油大学《 管理心理学(行政管理专业禁选)》在线考试
查看>>
机器学习(numpy/matplotlib/scipy)学习笔记
查看>>
HTML CSS JS 特殊字符表
查看>>
codeforces The Eternal Immortality 题解
查看>>
蓝桥杯 历届试题 幸运数 (堆+DFS)
查看>>
(SDUT 2159)山东省第一届ACM省赛 Ivan comes again! (set集合综合运用)
查看>>
微信js-sdk使用简述(分享,扫码功能等)
查看>>
selenium 的介绍和爬取 jd数据
查看>>
python-selenium优化方案
查看>>
服务器 centos 系统漏洞快速修复简易方法
查看>>