伪代码vhdl记录:
8个16bit数据排序,最后输出t0-t7,从大到小排列,如果t0和t1的数值一样大,t0排在前面(数值一样大的数据来源不同也区分,tx的x越小,排在前面)
将数据来源标号附在比较数据字段中。但是实际比较的时候不用这3bit,这样等到最后排序完成后,数据的低3bit表示的就是该数据的原始来源。
上图左侧信号是d端输入, t0_at_q是相应dff的q端信号。
在comp_load(比较启动)时,将初始数据load到8个q中。在进行比较过程中,如果swap_*信号为真,则交换相应的数据位置。
排序的算法如下:
- 数据每2个分一组,组内做好排序。
- 分组之后,相邻的两个组之间(a组和b组,a组在前),a组的第二个数(组内较小数)和b组的第一个数(组内较大数)作比较排序。
所以,能做2的排序的前提是1已经完成了组内的排序。 1和2的操作都是1拍完成一次交换排序。
swap_*相关信号如下:
- 如果16bit数据不相等,根据大小排序规则交换;
- 如果16bit数据相等,根据小的数据来源索引值在前的原则排序,所以当(t0的低3bit)>(t1的低3bit),说明t0的原始数据的索引是更大的值,t1更小,所以要交换。
代码中的4lpar等信号不用看。
排序过程在时序上交替完成排序算法步骤的1,2操作,即代码中的comp_even cycle 完成算法步骤1的组内排序;comp_odd cycle完成步骤2的相邻组间的数据交换排序。
even/odd标识是在启动排序(comp_load)的下一个cycle从0开始用1个bit信号翻转计数。
comp_par_q在比较期间每个cycle翻转取值,1‘b0表示even cycle,1’b1表示odd cycle。comp_run_q信号表示在比较过程中,comp_done表示比较过程结束的最后一个cycle。
当所有交换比较的信号swap_*都为0,说明没有需要交换顺序的数据了,数据已经全部排序完毕了。
如果一开始的输入数据就是符合最终排序,那么comp_load的下一个cycle,数据全部load到q中,comp_done信号即拉高,因为swap_*信号比较的是q端的数据。