# 最大次大值电路
**Repository Path**: RadishCake/maximum-submaximum-circuit
## Basic Information
- **Project Name**: 最大次大值电路
- **Description**: VHDL课程设计
- **Primary Language**: VHDL
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2021-01-06
- **Last Updated**: 2023-12-23
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# max_submax模块
这是最顶层的模块。整体的工作思路是先求出8个输入里面的最大值,之后通过把最大值变成"00000000",然后再做一次求最大值的运算,就能够得到次大值了。从整体上来看,就需要2个求最大值的模块——findmax模块,还有1个把最大值变成"00000000"的模块——max2zero模块。
整体都是通过组合逻辑电路实现的,理想状态下,不考虑电路的时延,是可以在一个周期内完成这个运算。为了提高输出波形的质量,需要加入时序逻辑部分。在工作频率较低的时候,时延的影响不大,在输出的时候,通过一个D触发器,就可以得到较好的结果。如果在频率较高的时候,组合逻辑部分的时延不能忽略,可以考虑在同一个clk下输出最大值,在下一个clk输出次大值,提供一个时钟周期的时间给它进行运算,提高整个电路的可靠性。
# findmax模块
整体采用逐位比较的思想,下面通过三张图片,简单描述它的工作过程。
从输入的最高位开始比较。从逻辑上分析可知,如果八个输入的最高位有 '1',那么最大值的最高位也必然是 '1'。用电路实现也很简单,这里把最高的8个位都视为“有效位”,将“有效位”进行“或”运算,结果就是最大值的最高位。之后把每一个位跟最大值“比较”,如果相同就是“有效”的,如果不同就是“无效”。转换为逻辑术语即每一位都跟“或”运算的结果进行“同或”运算,结果为'1'的就是有效位,反之为无效。
把同或的结果输出到第六位,要求得最大值的第六位,只需把有效状态,也就是绿色的部分进行”或“运算,结果就是最大值的第六位,输出的使能信号(状态信号)可以用上述方法求得。
根据第六位的使能输出,可以通过同样的方法求得最大值的第五位,以及相应的使能信号。值得注意的是,在高位已经被归为”无效“状态的,在低位中输出的状态也应该是”无效“的
依此类推,用8个`Unit_Compare`单元就可以得到八个8位宽输入的结果。
# max2zero模块
这个模块实现:输入8个8位宽的数据,以及它们的最大值,输出把最大值变成`"00000000"`之后的新的8个8位数.
实现的思路如下:
把每一个八位宽的输入都与最大值进行“异或”运算,最大值对应的输出即为`"00000000"`。
非最大值输出的结果中必然至少含有一个'1',把每一个八位宽的“异或”结果自己的八个位进行“或运算”,只有最大值输出'0',其余均为'1'
之后再把输入的8个8位宽数据逐位与它对应的”或“的结果进行”与“操作,便得到了最终输出的结果。
# unit_compare模块
unit_compare模块是整个电路最小的单元电路,用于求出最大值的某一位,下面是它的电路实现。
核心部分的是一个8输入的或门。
易知只要输入中含有'1','0'的数量对或门的输出是没有影响的。根据这一点,就可以把”禁用“状态的数据都变成'0',不管它原本是'1'还是'0'。可以通过一个与门实现这个效果,把该位的数据与该位对应的使能信号进行“与”运算,就能够得到这个效果。若该位的输入全是'0',那么最大值中该位也必然是'0',这与或门的输出结果是一致的,”禁用“状态也没有导致结果错误。
要输出下一个单元电路的使能信号,那么就需要对每一位和最大值的该位进行“比较”,这个比较可以通过一个“同或”门来实现,只要他们相同,就输出'1',不同就输出'0'。
考虑到使能信号是“传递”的,也就是说,它在输入的时候是禁用的,输出也必然会是禁用的。将进行“同或”运算比较之后的信号,与输入的使能信号做一次“与”运单,就能得到最终输出的使能信号。
经过上面这些运算就完成了一个单元电路的设计。一个单元电路消耗16个两输入与门,8个两输入同或门,1个八输入或门。