将一段C语言转化为Verilog

有时需要先用C语言完成某些设计,通过成熟的仿真软件验证后再转化为Verilog代码

#include <stdio.h>
int main(void){
  int n,A,B,C;
  A = 0;
  C = 7;
  scanf("n=%d",&n);
  while(C>=0){
  	B = ((A << 1) + (1 << C)) << C;
  	if(B <= n){
  		A += (1 << C);
  		n -= B;
	  }
	  C--;
  }
  printf("A=%d",A);
return 0;
}

 上面是一个将平方数开方的算法,将其转化为verilog代码

module sqrt(clk,rst_n,indata,result);
input             clk;
input             rst_n;
input      [31:0] indata;     //输入用32bits
output reg [15:0] result;     //结果开方只需16bits

reg [31:0] indata_reg;        //算法中需要更改输入,因此需要设置一个寄存
reg [31:0] B;
reg [4:0]  C;                 //indata的最大值为2的30次方,因此根据算法C = 15即可
reg [4:0]  C_temp;            //在循环中,计算A的值需要上一周期C的值,这里需要注意
reg [15:0] result_reg;        //用于检测结果是否发生变化,发生变化
wire flag_f;                  //用于在循环的计算中使相邻两个循环“互通”
wire flag_r;                  //用于在循环的计算中使相邻两个循环“互通”

assign flag_f = (B <= indata_reg && C != C_temp)?1'd1:1'd0;
assign flag_r = (result != result_reg);

always@(posedge clk or negedge rst_n)begin
   if(!rst_n)begin
	  result <= 16'd0;
	  indata_reg <= indata;
	end
	else if(B <= indata_reg && flag_r== 1'd0)begin
	   result <= result + (1 << C_temp);
	   indata_reg = indata_reg - B;
	end
	else begin
	  result <= result;
	  indata_reg <= indata_reg;
	end
end

always@(posedge clk or negedge rst_n)begin
   if(!rst_n)begin
		C = 5'd15;
		B <= indata + 1'd1;       //刚刚复位后,为了防止误判,将B设置为大于indata,不影响后面
	end
	else if(C != 31 && flag_f == 0)begin
	B <= ((result << 1'd1) + (1'd1 << C)) << C;
	C <= C - 1'd1;
	end
	else begin
	  C <= C;
	  B <= B;
	end
end
//以下两个always块是重点,分别有不同的作用
always@(posedge clk or negedge rst_n)begin
   if(!rst_n)begin
	   C_temp <= 5'd0;
	end
	else begin
	   C_temp <= C;
	end
end

always@(posedge clk or negedge rst_n)begin
   if(!rst_n)begin
	   result_reg <= 16'd0;
	end
	else begin
	   result_reg <= result;
	end
end

endmodule

       代码中重要的是,在C语言中,代码是顺序执行的,且可以把赋值语句加在循环的任何一个地方,因此本次循环可以使用本次循环或者相邻循环的值,而在Verilog中,不同值之间是并行改变的,相邻周期很容易会导致判断或者赋值语句不能够调用你所期待的,因此需要根据波形图去调整。波形图中的几个flag信号就是一些让循环正确运行的信号。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值