找回密码
 注册
关于网站域名变更的通知
查看: 228|回复: 1
打印 上一主题 下一主题

FPGA 之 SPI

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2019-7-4 16:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
本帖最后由 ulppknot 于 2019-7-4 16:50 编辑 ) k! }  ^) H% e: P) a1 I: e
& l# i& ^4 K: Z- {! {
module spi_ctrl(
8 K# l' d8 V, D5 \$ z/ Yinput wire        sclk,//系统时钟
5 l5 [5 d* {( B2 G1 Q! o) B2 binput        wire        rst_n,
; c" q* ]3 n0 f% j& `4 Kinput        wire        work_en,
7 U% J4 ~9 u9 K( Y; e( houtput        wire        spi_clk,
, E: D& j, _0 G1 F9 y" b9 S, Soutput        wire        spi_sdi,3 _3 Z$ g# L0 }0 U" E8 I
output        wire        spi_csn,
7 F, |9 L$ _# d) l/ }input        wire        spi_sdo$ U) {) @7 l. G; A5 A& ^/ Q
4 v) M: S* F3 k/ x: j
);5 z; K2 V; P6 [% }6 N, B
parameter        IDLE = 5’b0_0001;6 Q7 n. ^; X1 o
parameter        WAIT = 5’b0_0010;
. w6 x8 ]4 a1 P0 vparameter        R_MEM= 5’b0_0100;2 s( [: @$ }" i. Z# I
parameter        W_REG= 5’b0_1000;3 D2 @7 I) e" A+ ~4 a
parameter        STOP = 5’b0_0000;
  @% c8 @0 l: m. l% R# M
( I- e. C. Y. ^+ v, Uparameter        H_DIV_CYC        = 5’d25-1;//分频器(要给他写一个寄存器)实现分频50倍$ z& W7 q! x' e/ m# A% E

9 g. f" U' ^- L, q7 Areg        [4:0]        state;//状态机的寄存器变量,独热码,5个bit/ n$ W; q3 `2 a% _
reg        [4:0]        div_cnt;5 U& B0 n8 j& f& K
reg        clk_p=1’b1
) b) i/ l2 ]9 C; O! Swire        clk_n;//输出数据的时钟上升沿输出(与sclk相位相反)
  D  B$ g: Y" e# Q. sreg        pose_flag;
- \# a6 \: ]4 o1 }7 t. L8 vreg        [3:0]        wait_cnt;
, k0 L& {, R6 i/ f6 o  t; r1 \reg        [3:0]        shift_cnt;//16位数据2 x+ ^1 Z/ B1 A$ U
reg        [4:0]        r_addr;
* G. @- }8 q/ M1 l0 bwire        [15:0]        r_data;
$ ]0 g& I- _! m" zwire        wren;" D+ E- B* Y. H
reg        [15:0]        shif_buf;" ~' B. O) z4 B
reg        data_end;2 {; W4 G& [/ [# [. `
! a3 N; p. p6 s  n; ?4 f
//分频计数器1 o( V8 N6 k4 n
always        @(posedge sclk or negedge rst_n)//异步组合逻辑7 ~6 u9 A# f5 D. d5 Z
if(rst_n == 1’b0)
  ~% S8 a3 J8 c+ s& v: K( ydiv_cnt <=5’d0;//复位的时候给他清零
! a8 Y- N5 Y3 I) w9 Selse if(div_cnt == H_DIV_CYC )//计到24的时候清0
& x  m! d* }/ \! Sdiv_cnt <= 'd0;
1 O( S0 b2 a% oelse$ J* @  B# \6 l+ S9 w
div_cnt <= div_cnt + 1’b1;//一个加法器(未达到最大值累加)
: ?  `4 V, [; t4 _/ C2 O$ E//分频时钟不允许做寄存器的触发时钟,也就四不能写在alwaysk块的触发列表中2 _1 T$ n4 ^6 L: H- c; }8 I
always        @(posedge sclk or negedge rst_n)9 c7 }5 X8 S* s6 v
if(rst_n == 1’b0)* l( E' F  [8 i  o5 [/ J4 d
clk_p <= 1’b0;* {& a, [# I) C. I$ p
else if(div_cnt == H_DIV_CYC)0 k) h5 e% T4 S8 r5 K5 P6 e, Y
clk_p <= ~clk_p;//24反转一次一个周期就是50
9 q* @) [( U/ P/ f2 }; v4 E
& u0 F6 r3 [- X$ f- Sassign        clk_n=~clk_p;
: u# H2 r. x- m5 r' e; c% ^- i* B/ N3 Y  [6 {; J. I
always        @(posedge sclk or negedge rst_n)
" n6 ~& u( `0 i+ y( o# q9 Oif(rst_n == 1’bo). o, u" a7 ]4 X+ c0 t8 @/ W5 U
pose_flag <= 1’b0;
8 \, P5 z8 A/ Q! L& j- m5 }: relse if(clk_p == 1’b0&&div_cnt == H_DIV_CYC)
# M( `/ _' N7 j$ f( t. s" Y% gpose_flag <= 1’b1;; M7 M) B! }# V/ I7 Z6 \
else pose_flag <= 1’b0;
- L, D7 X' z0 o: S
2 ]. X5 M$ q* C0 F2 Balways        @(posedge sclk or negedge rst_n)//wait
& o; M0 r8 z6 O8 r5 `1 V! h; eif(rst_n == 1’b0); y% a+ r- I4 k, q5 i+ @' [0 Q( e0 n
wait_cnt<='d0;* ?4 _3 N7 T% F
else if(state == WAIT&&pose_flag == 1’b1)8 k# F& ]4 m  P2 l) M
wait_cnt <= wait_cnt + 1’b1;! `8 p8 \) J  L
else if(state !=WAIT)5 `: m, C' x9 {$ t
wait_cnt <= 4’d0;
: l: m/ I9 `. H* \# F; S, C4 f
' [( X" y* {) Z, x7 \% |# m//fsm两段式  F  S1 Y/ n/ f+ U+ j
always @(posedge sclk or negedge rst_n), T+ t0 o; E: a% {- U8 u
if(rst_n == 1’b0)
8 {* |/ \1 L6 w; Sstate <= IDLE;5 o3 k* \# u) X1 r8 z. A% c
else case(state)
9 t( A# t# P4 ^- J5 {8 jIDLE :if(work_en == 1’b1)
$ O% |, L0 w# v" f, K3 S- M, Bstate <= WAIT;" ~9 c5 g4 I  G
WAIT :if(wait_cnt[3] == 1’b1)//记到8的时候
/ M$ v' v) x, Y/ V4 Wstate <= R_MEM;  G7 D8 e7 I' K5 v. T9 _
R_MEM:state <= W_REG;/ F- X1 l5 T0 O4 p" I
W_REG:if(shift_cnt == 4’d15&&pose_flag == 1&&data_end!=1’d1)//写16个biit8个命令8个数据+ v; e9 K8 k4 g  b
state <= WAIT;
5 r3 w/ Z$ |( l: F- q, c9 A' j6 F6 h- Pelse if(shift_cnt == 4’d15&&pose_flag == 1&&data_end =1’d1)
/ h. J) B: i3 |8 d8 L7 ustate <= STOP;7 }2 ^/ Y# B% P$ m* f0 O
STOP: state <= STOP;, s! a! i3 }9 s
default:state <= IDLE;! b& j2 Z" B  H
endcase
2 k' K8 Z; e! F: K+ d- t4 b+ u8 P2 i- q% K
always        @(posedge sclk or negedge rst_n)//移位寄存器3 v( o; v" a7 R- C  b
if(rst_n == 1’b0)) {  k  F7 R5 i8 B3 X
shift_cnt <= 'd0;& v% c( c8 U3 ^$ h! c$ C( Y
else if(state == W_REG && pose_flag == 1’b1)
/ k/ d% _4 w& c6 T6 x0 S  {shift_cnt <=shift_cnt +1’b1;% k' K+ S" N  D! t$ U
else if( state !=W_REG); L$ {2 _* L- x6 [/ |
shift_cnt <= 4’d0;
' @+ J1 f3 P, l7 N& E! C8 k) V8 I+ i% f& s4 F4 b
//读mem的地址产生
" h" w# L5 S2 U5 |- Aalways        @(posedge sclk or negedge rst_n)
# Q! S: v2 S  X+ oif(rst_n == 1’b0)        
! o8 \0 u7 Q. g+ @- Rr_addr <= 'd0;
% C% @/ a) U6 b1 W1 velse if(state == R_MEM)
3 j9 W7 w, T5 f  ]' |1 s* [r_addr5 e" X& p( o! L1 i$ E

7 [1 n6 b% W8 _! }5 ]9 Aassign wren =1’b0;) ?% A1 h7 [% t/ J

' ?$ v& x7 Z7 _- V' u3 n, Y7 Calways        @(posedge sclk or negedge rst_n)
0 t, p3 V. O/ l' G$ s5 ~if(rst_n == 1’b0)        ; X( }, V8 a8 C& }- h
shif_buf<='d0;
: b7 c9 `1 ?+ z5 p& O' @4 B, Helse if(state == R_MEM)7 S" G# S( O# ]
shif_buf<=r_data;, K/ U* \% e* w# }- b
else if(state == W_REG&&pose_flag ==1’b1)
1 h% O" I2 c* x: f6 Y* qshif_buf <= {shif_buf[14:0]& u! t/ S, f& J6 {9 ~
5 K& {& ?+ n5 s% a8 ~$ z$ Y
ram_1632_sr        ram_1632_sr_inst (! q8 J7 ?  p# T: \1 g
.address ( address_sig ),//读地址
: \4 g3 V1 k9 g.data ( 16’d0 ),//写数据
  W' Y, C- Z8 R; w* R.inclock ( sclk ),
  q+ G+ C& {# \.wren ( wren ),//写使能高有效
2 Z" [3 u% _: j. \5 p.q ( r_data ). ], E9 T; U) v" d- m7 x
);
! B7 E' J5 H8 \3 m! d
# z0 E) i, o: m; S. d- V4 Fendmodule; _! Q  a( P, |9 B. {$ v

" v- Z4 A' U0 N0 Q# L6 Y+ i  q/ f* I; b# d+ A" `

该用户从未签到

2#
发表于 2019-7-4 16:51 | 只看该作者
谢谢楼主分享
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-10-11 09:00 , Processed in 0.125000 second(s), 23 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表