数字 11 verilog实现通用二分法

最近想做一个通用二分法,所谓通用,就是对不同的位宽的数据都能做二分法,比如输入4bit。能够按照8->12->14->13的顺序开始做二分法。输入2bit,能够按照2->3的顺序做二分法。

假设输入N,那么就会从N/2开始做二分法。

我这个二分法是作用于反馈系统的,此二分法的当前输出,是与比较结果(比较结果决定二分法的下一次分区)相关的。

使用verilog语言实现的话,我这里暂时想出了一种思路。

以下面这个二分法流程为引。

进程cnt_id=0 : 比较结果为0表示二分法向下 32->16 100000-> 010000

进程cnt_id=1 : 比较结果为1表示二分法向上 16->24 010000-> 011000

进程cnt_id=2 : 比较结果为0表示二分法向下 24->20 011000-> 010100

进程cnt_id=3 : 比较结果为0表示二分法向下 20->18 010100-> 010010

进程cnt_id=4 : 比较结果为1表示二分法向上 18->19 010010-> 010011

根据以上这个流程可以总结出几点规律:

1 每次做二分法的数据位宽只有2bit,其他bit都不变。

2 做二分法的数据位置,根据进程变化。比如进程是0时,数据只有最高位和次高位变化。数据操作依次右移。

3 做二分法的2bit数据中,高位会与比较结果相等,低位的结果都是从0变成1。

那么,我的思路是做一个数据刷子,这个刷子把原数据刷一下,就变成了二分之后的数据。

这个刷子是这么做的。

首先根据异或xor的运算规则。

根据0 ^ 0 = 0,0 ^ 1 = 1 可得0 ^ n = n

根据1 ^ 0 = 1,1 ^ 1 = 0 可得1 ^ n = !n

那么以此运算规则为基础,根据上面总结的二分法的规律,数据bit不变的地方,我让它异或0,bit变为比较结果的地方,我让他异或(比较结果的取反),从0变成1的地方,我让它异或1就可以了。

所以我构造的刷子就出来了。

[!cmp_in,1’b1]根据cnt_id右移位,其他位补0

用这个刷子,去异或原数据,比如

进程cnt_id=0 : 比较结果为0表示二分法向下 32->16 100000(->010000)

我的刷子是110000,那么110000异或100000是010000。

进程cnt_id=1 : 比较结果为1表示二分法向上 16->24 010000 (->011000)

我的刷子是001000,那么001000异或010000是011000。

依次类推。

写成代码我是这么写的

result <= result ^ ({!cmp_in,1’b1}<<(REG_WIDTH-2-cnt_id))

空位的话verilog会自动补0的。

我这个思路其实我自己感觉还有些奇怪的地方,比如这句话是不是逻辑过多的。

先记录一下,以后有问题再回来总结。

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!要使用Verilog实现逐次逼近二分法,您可以按照以下步骤进行: 1. 首先,确定输入和输出的格式。对于逐次逼近二分法,您需要输入一个初始区间(例如上界和下界),以及一个目标精度。输出将是逼近的结果。 2. 创建一个顶层模块,定义输入和输出端口。例如: ```verilog module binary_search( input wire [31:0] upper_bound, input wire [31:0] lower_bound, input wire [31:0] target_precision, output reg [31:0] result ); ``` 3. 在模块内部,定义所需的变量和信号。例如: ```verilog reg [31:0] mid_point; reg [31:0] current_precision; ``` 4. 实现逐次逼近二分法的逻辑。这包括计算中点、当前精度和比较结果。例如: ```verilog always @(posedge clk) begin if (reset) begin // 初始化变量和信号 end else begin // 计算中点 mid_point <= (upper_bound + lower_bound) >> 1; // 计算当前精度 current_precision <= upper_bound - lower_bound; // 比较中点与目标精度 if (current_precision <= target_precision) begin // 达到目标精度,输出结果 result <= mid_point; end else begin // 调整上界或下界 if (mid_point > target) begin upper_bound <= mid_point; end else begin lower_bound <= mid_point; end end end end ``` 请注意,上面的代码仅为示例,具体实现可能会有所不同,具体取决于您的设计要求和硬件平台。 希望以上信息对您有所帮助!如果您还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值