结构框图如图所示,和SHA256非常类似。
然后说明了一下你的设计大概是怎么样的。
粗略估计了一下需要的时钟周期,上述是采用串行实现的。因此需要的时钟周期较长。
如果采用并行的话,可以大幅加快运算速度。因为对于不同的nonce而言,它们互相之间的运算是完全独立的。所以完全可以并行运算,这就是典型的用空间换时间。
至于它的写法也非常简单,只需要采用一个for循环语句,在运算阶段例化多次即可(这种方式有点类似于GPU,GPU能取得大幅成功的原因也主要在于它的并行计算能力)。
需要注意,上述方式会产生大量的逻辑资源,实际设计过程中是否需要采用这种方式需要谨慎考虑。通常来说,对于计算密集型、不太依赖于IO资源的任务,采用并行化可以有效提高吞吐量,减少运算时间(并不是提高时钟频率,这一点需要注意!)
同样还可以通过例化多个模块来实现。
剩余的课件是一些实验细节的东西,这里就不拿出来讲了。有两页PPT我觉得比较有意义,单独说明一下:
- 对于一个任务而言,有很多种实现方式,所以没有绝对的“正确的方法”
- 好的经验法则是使代码易于阅读
- 如果有大量嵌套的if/else语句的话,代码会变得难以阅读,可以尝试简化代码,这会让你更好的实现你的设计(实际上对于大量嵌套的if/else语句而言,可以考虑用状态机的写法来实现。因为状态机的本质在于反馈,而if/else本质上是隐式的状态机(时序逻辑是隐式状态机,组合逻辑是MUX))。
- 如果减少状态,需要增加大量的if/else语句,那这并不是一个好方法。因为这本质上也会产生很多状态(隐式状态机)
- 这个Project理论上可以用300~400行代码实现
这里我再强调一下,状态机的本质在于有没有反馈!在数字电路中,关键在于你当前的Q端输出是否会对你下一轮的Q端输出产生影响!因此本质上一个计数器,0、1、2、3这种的也是一个状态机!你完全可以用状态机的写法去实现它,没有任何本质区别。
因此我建议一定要写成三段式,不要用state表示。用next_state和current_state表示寄存器的D端和Q端,可以让你充分的与实际的数字电路结合。这一点非常重要。
看到没,一个计数器也是一个状态机。cnt_q就是state,cnt_d就是next_state。通过一个加法器去计算next_state,然后吧next_state通过D触发器寄存给state。基于这个大家应该能理解if/else为什么大部分情况下是隐式状态机。因为有反馈啊!
还有你写的软件,C语言,汇编代码本质都是状态机,状态机思想博大精深,大家好好理解一下。
使用模块化设计的方式,在前期调试过程中可以让这个数字小一点,更便于你的调试。