我正在尝试用Verilog / SystemVerilog编写可合成的3D光栅化器。光栅化器现在不是真正的3D光栅化器:它只接收六个32位浮点数用于顶点位置(vertA_pos_x,vertA_pos_y,vertB_pos_x,vertB_pos_y,vertC_pos_x,vertC_pos_y)和九个8位整数用于顶点着色(vertA_color_r,vertA_color_g,vertA_color_b) ,vertB_color_r,vertB_color_g,vertB_color_b,vertC_color_r,vertC_color_g,vertC_color_b)。
位置'范围是0.0f~1.0f,0.0f表示屏幕的上/左侧,0.5f表示中间,1.0f表示底部/右侧。
光栅工作首先要计算需要多少光栅线。假设帧缓冲区高度为240像素,顶点A是顶部顶点,B是左下角,C是右下角,X是最下面的顶点(B或C;必须计算),栅格线的数量由(vertX_pos_y - vertA_pos_y) / 240
给出。
光栅化过程的这一部分非常复杂,足以暴露我的疑虑,所以我将不再解释如何继续进行。
现在我想知道的是如何在Verilog中实现这种“复杂”逻辑(它是“复杂的”,因为它是顺序的并且需要一个以上的时钟周期,这不是设计中最令人愉快的事情使用硬件描述语言。)
我正在使用Altera的Quartus,所以我主要对Altera解决方案感兴趣。
Quartus附带的浮点运算宏功能都需要一个以上的时钟周期来完成,因此,为了实现像(vertX_pos_y - vertA_pos_y) / 240
这样的“简单”计算,我假设一个相当无聊的写入和容易出错的状态机是必要的。我最大的期望是有人会告诉我我不需要那个,但如果不是这样,我仍然想知道人们通常如何设计这样的东西。
另外请注意,我对Verilog和硬件设计都很陌生,所以如果我说一些愚蠢的话,我很抱歉。想法?
答案 0 :(得分:4)
你听说过流水线吗?这就是数据路径的构造方式。
举一个例子,假设你想做(a*b) + c
,其中x*y
需要3个时钟周期而x+y
需要1个时钟周期。流水线操作只是意味着插入寄存器组来排列延迟。在该示例中,输入c
被延迟以与乘法的等待时间匹配。总的来说,操作的延迟为3 + 1 = 4个时钟周期。
现在,如果您需要进行大量计算,可以将管道延迟“放在一起”,这样您就不需要状态机逻辑来安排数学运算。这意味着您将需要等待几个周期才能得到答案(即延迟) - 这在同步设计中是不可避免的。