微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > 磕头求助关于Verilog HDL的一段小程序

磕头求助关于Verilog HDL的一段小程序

时间:10-02 整理:3721RD 点击:
在做毕业设计,其中一部分需要用到FPGA采集数据,用ARM来隔一段时间通过SPI采集一次数据,因此编写了一个简单的仿SPI从机的小程序,因为新手,遇到了折腾一个月也没解决的问题,试用过状态机的方法,移位寄存器的方法,还有目前的类似于数组指针的方法,统统出现一个问题,就是仿真没有问题,但是下载到片内就不正常运行。最近两天用Technology Map Viewer(我用Quartus II 9.0)看,发现有好几个寄存器被优化掉了,而且本来应该在下降沿发生计数变化的,居然在上升沿也会跳变,总之实际结果与预想结果相差太远,实在是没有办法了,身边没有人教,纯粹自学,由于关系到毕业设计,所以还请各位大哥大姐大叔大婶大爷大妈,行行好,帮我看看究竟怎么回事,该怎么解决这个问题啊,俺给您磕头了。
以下为源程序:
module spi(SCK,MOSI,MISO,SSEL,RevData);
input SCK;
input MOSI;
input SSEL;
output reg MISO;
wire temp;
output [7:0]RevData;
reg [7:0]Data;
wire [7:0] ParaData;
assign ParaData=8'h72;
spimod myspi(.SCK(SCK),.SSEL(SSEL),.MISO(temp),.MOSI(MOSI),
             .ParaData(ParaData),.RevData(RevData));
endmodule
///////////////////////////////////////////////////////
module spimod(SCK,SSEL,MISO,MOSI,ParaData,RevData);
input SCK;
input SSEL;
output reg MISO;
input MOSI;
input [7:0] ParaData;
reg [3:0] ShiftCount;
reg [15:0] ShiftReg;
wire ShiftClock;
output reg [7:0] RevData;
assign ShiftClock=SCK | SSEL;
always @(negedge ShiftClock)
begin
  if(ShiftCount>=4'h8)
  ShiftCount<=4'b0000;
  else
  ShiftCount<=ShiftCount+1'b1;
end
always @(posedge SCK)
begin
  MISO<=ShiftReg[16-ShiftCount];
end
always @(negedge SSEL)
begin
  ShiftReg[15:8]<=ParaData;
end
always @(negedge SCK)
begin
  ShiftReg[7:1]<=ShiftReg[6:0];
  ShiftReg[0]<=MOSI;
end
always @(posedge SSEL)
begin
  RevData<=ShiftReg[7:0];
end
endmodule
再磕三个响头了……谢谢

看得出来,这是个对V不熟的人写的

1# benselang

不要屈膝  

没有输入输出时序图,别人也忙不了你
MISO<=ShiftReg[16-ShiftCount]; // 这么设计不行
SSEL 应该是一个高低8位的选择,不要作为时钟

我有一个建议,就是最好只有一个时钟,单时钟设计

这种沿触发的 最好就一个时钟信号 你这里沿触发信号太多

建议你引入一个外部时钟信号 比如clock 用clock来采样其它信号 比如SCK SSEL等

小编 仔细弄明白啥是同步设计才行

谢谢各位,忘了发时序图了   (SPI通信时序,主机SCK高电平有效,下降沿采样,SSEL低电平有效)
                ___        ___        ___       ___        ___        ___       ___        ___
SCK _____|      |___|     |___|     |___|     |___|      |___|     |___|     |___|     |____
SSEL__                                                                                                                  ____
            |________________________________________________________|      
小弟确实是超级菜鸟,只是找了两本书自学,而且想针对毕业设计来做,所以没有深入系统学,各位大大,还请多多帮忙,实在是关系重大,可否请详细指明该怎样修改?或者可否举一小例子说明。
实在是恳求各位大大了

另外,补充一点点,我的基本思路是在SSEL下降沿时从外部总线采集数据到ShiftReg[15:8](因为最后需要做到用当主机ARM采集16个字节的信息,所以从机FPGA连续16次从不同的寄存器读取数据)。

output reg MISO;  
为什么又是output 又是reg 没看到这么写的 不过编译居然能通过哎
前段时间调过一个简单的spi  大叔我就帮你看看吧

实在看不懂你的代码 spi通信的话只有SCK MISO MOSI CS 四个信号
你的ParaData RevData是干什么的 从哪儿来到哪儿去也没说明白 想帮你我也帮不上忙的

为什么又是output 又是reg
那是verilog2001的新语法。

output reg 标准语法格式

always为一个语句时,就不需要用begin......end了!

回复楼上的那位大叔
output MISO; reg MISO; 或者 reg temp; assign MISO=temp;这是两种常用的方法我用的output reg MISO 其实和上面的一样,从一本书上看来的。另外,不知道您年龄多大,请您不要随便做别人的长辈。或者做别人的晚辈。“大叔,我帮你看看吧”,呵呵,开个玩笑谢谢您的回答
SPI通信没错是包括MISO,MOSI,SCK,SSEL(CS),但是这只是对外的引脚,那么模块内部怎么把数据输入到SPI移位里边以及怎么把以为得到的数据得出呢?
我用了ParaData表示并行输入spi模块的数据,用RevData表示从SPI模块输出的接收到的并行数据,如此而已,如果有描述不清楚的地方还请见谅

你的问题在于头脑中几乎没有HW的概念,没有想过你键盘下的code对应怎样的HW单元,完全是抽象的写verilog code,不符合HW的规范,肯定综合不出自己想要的结果。最好还是先理一下思路,能不能尽量搞一个稍微详细的硬件模块图来。然后再写code.

想学习。

16# tbb2009
您好,请问您说的HW是HardWare的缩写吗?
个人是个新手,只用过单片机和ARM,不足之处请见谅,可能思路还是按照编写单片机的方式来写的,但是有点问题,Verilog不是可以进行行为级别的建模吗?我直接描述行为应该也可以吧。
我现在实际做的就是一个模块spimod,顶层模块spi只是为了用ARMSPI读出时判别是否正常运行而给了几个值而已,如有不对,还请详细指教。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top