本帖最后由 zhaironghui 于 2015-10-22 11:26 编辑
大家好,接触 Verilog 时间不长,遇到一个问题,真心求教。谢谢
背景:想把 AD 输出的 8 位并行数据在 CPLD 中进行并串转换,并在 DSP 提供的 串行时钟 CLKR1 和 帧同步(片选)信号 FSR1 的控制下,将串行数据经 DR1 引脚输出
问题:综合能通过,但经过波形仿真,DR1 输出的数据总是不对
代码如下:
//
module spi(
output reg clk_ad,
//SPI_1,方向:CPLD-->DSP
output reg DR1,
input FSR1,
input CLKR1,
input clk_in,
input [7:0]data_in //AD输入cpld的8位数据
);
reg[4:0]temp;
//add
reg[7:0]data_to_dsp; //用于数据缓存
reg[8:0]data_to_dspp;
//AD的时钟由有源晶振4分频得到,10/4=2.5M
always @(posedge clk_in) begin
temp<=temp+1'd1;
if(temp==1)
begin
clk_ad<=~clk_ad;
temp<=0;
end
else
clk_ad<=clk_ad;
end
//AD输入到CPLD的数据转移到寄存器data_to_dsp中
always @(posedge clk_ad) begin
data_to_dsp<=data_in;
end
//CPLD到DSP的SPI实现(SPI1)
always @(negedge CLKR1) begin
if(!FSR1)
begin
data_to_dspp[8:0] <= {data_to_dsp[7:0],1'b0};
DR1 <= data_to_dspp[8];
end
end
endmodule
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
我觉得问题出在这句上:
begin
data_to_dspp[8:0] <= {data_to_dsp[7:0],1'b0};
DR1 <= data_to_dspp[8];
end
以data_to_dsp为1010_1010为例,我猜楼主的意思是用1'b0把data_to_dsp里的数据一位一位挤出去,所以data_to_dspp会变成这样:1010_1010_0,然后dr1就把最高位取走了,但问题是data_to_dsp一直是1010_1010的话,data_to_dspp会一直是1010_1010_0,所以dr1取到的永远是data_to_dsp的最高位。我觉得如果加一句,变成这样:
begin
data_to_dspp[8:0] <= {data_to_dsp[7:0],1'b0};
data_to_dsp<=data_to_dspp[7:0];
DR1 <= data_to_dspp[8];
end
第一个时钟输出还是最高位1,但是这时候data_to_dsp变成了0101_0100_0,下个时钟来的时候你就能取到想要的0了。不知道我这样理解对不对,请过路大神指点。
另外提出几点疑问,如果我上面说的是对的,存在两个个问题,
1.是不是要个计数器看看数据都挤出去了就停了吧;
2.这句话:
always @(posedge clk_ad) begin
data_to_dsp<=data_in;
end
会在每个时钟把data_to_dsp刷一遍,这样两个时钟相同的话,可能还是一直取到数据的最高位那个1....
以上。
1、CLKR1也是2.5M?2、AD采样数据并转串的时候使用的是CLKR1,该时钟与ADC的时钟的关系不确定;建议加一个异步FIFO
不会写 testbench 额
"pouty7447"应该指出了问题所在,之前没有仔细看代码。
其实应该没有必要定义一个data_to_dspp,即将data_to_dsp与data_to_dspp合并;还是只需要一句话:
data_to_dsp[8:0] <= {data_to_dsp[7:0],1'b0};
当然前面定义的时候:reg[8:0] data_to_dsp
当然,数据采集的时钟频率,以及每个数据什么时候开始转换,且何时转换结束,都是需要后续考虑的问题。
一周热门 更多>