最近在写SPI与ADC通信,向往ADC中配置寄存器,在写连续发送模块的时候,发送24位的寄存器数据,但是在该模块中添加的时钟计数器count,但总是计数不正确,设置计数到95时为0,但仿真时总是计数到127为0,反复检查代码也看不出是哪里的问题?求大佬解答。下边是连续模块的代码。
module ADC_config
(
output reg config_rx
);
initial
begin
config_rx<=1'b1;
end
//寄存器配置
initial
begin
#(5208*20); //给起始位一位的延时时间
rx_24bit(24'd1);
rx_24bit(24'd2);
rx_24bit(24'd4);
end
//task rx_16bit
//(
//input [15:0] data
//);
//integer i;
//for(i=0; i<18; i=i+1)
//begin
//case(i)
//0:config_rx<= 1'b0;
//1: config_rx <= data[0];
//2: config_rx <= data[1];
//3: config_rx <= data[2];
//4: config_rx <= data[3];
//5: config_rx <= data[4];
//6: config_rx <= data[5];
//7: config_rx <= data[6];
//8: config_rx <= data[7];
//9: config_rx <= data[8];
//10: config_rx <= data[9];
//11: config_rx <= data[10];
//12: config_rx <= data[11];
//13: config_rx <= data[12];
//14: config_rx <= data[13];
//15: config_rx <= data[14];
//16: config_rx <= data[15];
//17: config_rx <= 1'b1;
// endcase
//#(5208*20); //每发送1位数据延时5208个时钟周期
// end
//endtask //任务以endtask结束
task rx_24bit(
input [23:0] data24
);
integer i; //定义一个常量
for(i=0; i<26; i=i+1)
begin
case(i)
0:config_rx<= 1'b0;
1: config_rx <= data24[0];
2: config_rx <= data24[1];
3: config_rx <= data24[2];
4: config_rx <= data24[3];
5: config_rx <= data24[4];
6: config_rx <= data24[5];
7: config_rx <= data24[6];
8: config_rx <= data24[7];
9: config_rx <= data24[8];
10: config_rx <= data24[9];
11: config_rx <= data24[10];
12: config_rx <= data24[11];
13: config_rx <= data24[12];
14: config_rx <= data24[13];
15: config_rx <= data24[14];
16: config_rx <= data24[15];
17: config_rx <= data24[16];
18: config_rx <= data24[17];
19: config_rx <= data24[18];
20: config_rx <= data24[19];
21: config_rx <= data24[20];
22: config_rx <= data24[21];
23: config_rx <= data24[22];
24: config_rx <= data24[23];
25: config_rx <= 1'b1;
endcase
#(5208*20); //每发送1位数据延时5208个时钟周期
end
endtask //任务以endtask结束
//发送32位寄存器的任务
task rx_32bit(
input [31:0] data32
);
integer i; //定义一个常量
for(i=0; i<34; i=i+1)
begin
case(i)
0:config_rx<= 1'b0;
1: config_rx <= data32[0];
2: config_rx <= data32[1];
3: config_rx <= data32[2];
4: config_rx <= data32[3];
5: config_rx <= data32[4];
6: config_rx <= data32[5];
7: config_rx <= data32[6];
8: config_rx <= data32[7];
9: config_rx <= data32[8];
10: config_rx <= data32[9];
11: config_rx <= data32[10];
12: config_rx <= data32[11];
13: config_rx <= data32[12];
14: config_rx <= data32[13];
15: config_rx <= data32[14];
16: config_rx <= data32[15];
17: config_rx <= data32[16];
18: config_rx <= data32[17];
19: config_rx <= data32[18];
20: config_rx <= data32[19];
21: config_rx <= data32[20];
22: config_rx <= data32[21];
23: config_rx <= data32[22];
24: config_rx <= data32[23];
25: config_rx <= data32[24];
26: config_rx <= data32[25];
27: config_rx <= data32[26];
28: config_rx <= data32[27];
29: config_rx <= data32[28];
30: config_rx <= data32[29];
31: config_rx <= data32[30];
32: config_rx <= data32[31];
33: config_rx <= 1'b1;
endcase
#(5208*20); //每发送1位数据延时5208个时钟周期
end
endtask //任务以endtask结束
endmodule
连续发送模块 :
module ADC_wr_seq
#(
parameter data_in_max=23
//parameter data_in_max='d31
)
(
input wire sys_clk,//系统时钟
input wire sys_rst,
input wire [data_in_max:0] data_in,//输入数据
input wire in_flag,//输入标志位
output reg sclk,//输出SPI时钟
output reg cs,//片选使能
output reg mosi//输出
);
//状态
localparam IDLE=2'b00;
localparam WR_EN=2'b01;
localparam count_width=6;
localparam count_max='d95;
localparam cnt_bit_max='d23;
localparam cnt_bit_binary_max='d4;
reg [count_width:0] count;//因为输入为16位,所以要计数到64,当后边需要配置24.32位数据时,这里的计数要相应的改为96,128。
reg [1:0] state;
reg [1:0] cnt_byte;//字节数,在一个SPI写时序中需要几个字节数
reg [1:0] cnt_sclk;//时钟计数,设置的SPI时钟为12.5M,左移需要4分频, 所以选择计数为0.1.2.3。
reg [cnt_bit_binary_max:0] cnt_bit;//因为传输的是16位,所以位数计数器为0-15,后边根据传输数据的变化会相应改变。
//产生时序计数,记录一个字节所需要的时钟周期
always@(posedge sys_clk or negedge sys_rst)
if(!sys_rst)
count<='d0;
else if(state!= IDLE)
count<=count+1'b1;
else if(count==count_max)
count<='d0;
//产生字节标志计数器,记录一次传输过程中要有几个字节标志
always@(posedge sys_clk or negedge sys_rst)
if(!sys_rst)
cnt_byte<=2'd0;
else if((count==count_max)&&(cnt_byte==2'd2))
cnt_byte<=2'd0;
else if(count==count_max)
cnt_byte<=cnt_byte+1'd1;
//产生SPI时钟计数计时器
always@(posedge sys_clk or negedge sys_rst)
if(!sys_rst)
cnt_sclk<=2'd0;
else if((state==WR_EN)&&(cnt_byte==2'd1))//范围大的时候可以用大于小于,一般不要轻易使用
cnt_sclk<=cnt_sclk+1'b1;
else if (cnt_sclk==2'd3)
cnt_sclk<=2'd0;
//产生输出时钟sclk
always@(posedge sys_clk or negedge sys_rst)
if(!sys_rst)
sclk<=1'b1;
else if(cnt_sclk==2'd3)
sclk<=1'b1;
else if(cnt_sclk==2'd1)
sclk<=1'b0;
//产生输入数据位数计数器
always@(posedge sys_clk or negedge sys_rst)
if(!sys_rst)
cnt_bit<='b0;
else if(cnt_sclk==2'd3)
cnt_bit<=cnt_bit+1'd1;
else if(cnt_byte==2'd2)
cnt_bit<='b0;
//产生片选使能信号
always@(posedge sys_clk or negedge sys_rst)
if(!sys_rst)
cs<=1'b1;
else if(state==IDLE)
cs<=1'b1;
else if(state==WR_EN)
cs<=1'b0;
//状态跳转
always@(posedge sys_clk or negedge sys_rst)
if(sys_rst== 1'b0)
state <= IDLE;
else
case(state)
IDLE: if(in_flag == 1'b1)
state <= WR_EN;
WR_EN: if((cnt_byte == 2'd2) && (count ==count_max))
state <= IDLE;
default: state <= IDLE;
endcase
//数据输出
always@(posedge sys_clk or negedge sys_rst)
if(sys_rst == 1'b0)
mosi <= 1'b0;
else if((state == WR_EN) && (cnt_byte == 2'd2))
mosi <= 1'b0;
else if((state == WR_EN)&&(cnt_byte == 2'd1) && (cnt_sclk == 2'd0))
mosi <= data_in[data_in_max - cnt_bit];
endmodule
改成
module adder_tp();
wire cout,
wire[3:0] sum,
reg[3:0] a,
reg[3:0] b,
reg cin
// 这样写比较简单,可能会影响其他时序的判断
always@(posedge sys_clk or negedge sys_rst)
if(!sys_rst || count >= count_max)
count<='d0;
else if(state!= IDLE)
count<=count+1'b1;
// 这样写好像可靠些
always@(posedge sys_clk or negedge sys_rst)
if(!sys_rst)
count<='d0;
else if(state!= IDLE)
begin
if(count < count_max)
count<=count+1'b1;
else
count<='d0;
end