|
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" `
|
|