信号列表:
项目要求:
模块工作时钟为100MHz;
当收到din_vld=1时,产生要求的波形。其中SCK的周期为1M;MOSI输出值为8'h37;
SCK和MOSI可以允许由20ns的偏差。
设计思路:
8个bit,一个bit是1M=1000ns,模块时钟是100MHz=10ns,因此一个bit是需要有100个周期的,首先设计两个计数器。一个数每个bit中的时钟周期的个数(数那100个),另一个数有多少了bit(8个bit);
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt0 <= 0;
end
else if(add_cnt0)begin
if(end_cnt0)
cnt0 <= 0;
else
cnt0 <= cnt0 + 1;
end
end
assign add_cnt0 = flag_add;
assign end_cnt0 = add_cnt0 && cnt0==100-1 ;
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt1 <= 0;
end
else if(add_cnt1)begin
if(end_cnt1)
cnt1 <= 0;
else
cnt1 <= cnt1 + 1;
end
end
assign add_cnt1 = end_cnt0;
assign end_cnt1 = add_cnt1 && cnt1== 8-1;
接下来就是设计SCK信号,我们让SCK信号在每bit中数周期的时候,数到第一个周期的时候开始变为1,数到一半变为0;
这样就有了我们的SCK信号:
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
sck <= 0;
end
else if(add_cnt0 && cnt0==1-1)begin
sck <= 1;
end
else if(add_cnt0 && cnt0==50-1)begin
sck <= 0;
end
end
对于MOSI的数据输出,在初始值的位置赋值,设计如下代码:
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
mosi <= 0;
end
else if(add_cnt0 && cnt0== 1-1)begin
mosi <= data[7-cnt1];
end
end
assign data = 8'h37;
这样我们就设计完了我们所需要的信号,但是我们还需要继续补充一个flag_add的信号,这个是我们自己设计的信号:
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
flag_add <= 0;
end
else if(en)begin
flag_add <= 1;
end
else if(end_cnt1)begin
flag_add <= 0;
end
end
此时,就完成了我们的项目。
完整代码如下:
module SPI_1(
clk ,
rst_n ,
,
en ,
sck ,
mosi
);
input clk ;
input rst_n ;
input en ;
output mosi ;
output sck ;
reg mosi ;
reg sck ;
reg flag_add;
reg [6:0] cnt0 ;
reg [4:0] cnt1 ;
wire add_cnt0;
wire end_cnt0;
wire add_cnt1;
wire end_cnt1;
wire [7:0] data ;
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt0 <= 0;
end
else if(add_cnt0)begin
if(end_cnt0)
cnt0 <= 0;
else
cnt0 <= cnt0 + 1;
end
end
assign add_cnt0 = flag_add;
assign end_cnt0 = add_cnt0 && cnt0== 100-1;
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt1 <= 0;
end
else if(add_cnt1)begin
if(end_cnt1)
cnt1 <= 0;
else
cnt1 <= cnt1 + 1;
end
end
assign add_cnt1 = end_cnt0;
assign end_cnt1 = add_cnt1 && cnt1== 8-1;
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
flag_add <= 0;
end
else if(en)begin
flag_add <= 1;
end
else if(end_cnt1)begin
flag_add <= 0;
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
sck <= 0;
end
else if(add_cnt0 && cnt0== 1-1)begin
sck <= 1;
end
else if(add_cnt0 && cnt0== 100/2-1)begin
sck <= 0;
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
mosi <= 0;
end
else if(add_cnt0 && cnt0== 1-1)begin
mosi <= data[7-cnt1];
end
end
assign data = 8'h37;
endmodule
仿真波形:
很明显地看出来,MOSI的输出是00110111,就是16进制的37,其他信号都是按照要求设计的。