FPGA verilog他山之石系列(新手入门必备代码)4 查找表的两种写法

Posted by

FPGA构建查找表是我们常用,而且读取速度可以根据情况控制在一个时钟之内(组合电路)或者一个时钟之后(时序电路)。

所谓的大型查找表,一般都有几千或者上万的数据。

来,我们来看工程中实际一个例子:

module lookup_table(
	input clk ,
	input rst ,
	input wire [11:0] rx_number,
	
	output reg [14:0] tx_number

);
always@(posedge clk or negedge rst)begin
if(rst == 1'b0)
tx_number <= {1'b1,1'b1,4'd15,9'd511};
else
case (rx_number)      

//子板1
        12'd553     :       tx_number <= {1'b0,1'b0,4'd1,9'd0};
        12'd554     :       tx_number <= {1'b0,1'b0,4'd1,9'd1};
        12'd555     :       tx_number <= {1'b0,1'b0,4'd1,9'd2};
        12'd556     :       tx_number <= {1'b0,1'b0,4'd1,9'd3};
        12'd557     :       tx_number <= {1'b0,1'b0,4'd1,9'd4};
        12'd558     :       tx_number <= {1'b0,1'b0,4'd1,9'd5};
        12'd559     :       tx_number <= {1'b0,1'b0,4'd1,9'd6};
        12'd560     :       tx_number <= {1'b0,1'b0,4'd1,9'd7};
        12'd561     :       tx_number <= {1'b0,1'b0,4'd1,9'd8};
        12'd562     :       tx_number <= {1'b0,1'b0,4'd1,9'd9};
        12'd563     :       tx_number <= {1'b0,1'b0,4'd1,9'd10};
        12'd564     :       tx_number <= {1'b0,1'b0,4'd1,9'd11};
        12'd529     :       tx_number <= {1'b0,1'b0,4'd1,9'd12};
        12'd530     :       tx_number <= {1'b0,1'b0,4'd1,9'd13};
        12'd531     :       tx_number <= {1'b0,1'b0,4'd1,9'd14};
        12'd532     :       tx_number <= {1'b0,1'b0,4'd1,9'd15};
        12'd533     :       tx_number <= {1'b0,1'b0,4'd1,9'd16};
        12'd534     :       tx_number <= {1'b0,1'b0,4'd1,9'd17};
        12'd535     :       tx_number <= {1'b0,1'b0,4'd1,9'd18};
        12'd536     :       tx_number <= {1'b0,1'b0,4'd1,9'd19};
        12'd537     :       tx_number <= {1'b0,1'b0,4'd1,9'd20};
        12'd538     :       tx_number <= {1'b0,1'b0,4'd1,9'd21};
        12'd539     :       tx_number <= {1'b0,1'b0,4'd1,9'd22};
        12'd540     :       tx_number <= {1'b0,1'b0,4'd1,9'd23};
.........

	default	   :	    tx_number <= {1'b1,1'b1,4'd15,9'd511};
		
	endcase
	

还有一种基于 if else 构建

//根据温度区间来产生控制输出

always @(*)begin
      if ( zb_temp == -55 )                      D_data_rx = {8'h18,16'd65536}   ;
else  if ( zb_temp <= -45 && zb_temp > -55 )      D_data_rx = {8'h18,16'd60345}   ;
else  if ( zb_temp <= -35 && zb_temp > -45 )      D_data_rx = {8'h18,16'd58770}   ; 
else  if ( zb_temp <= -25 && zb_temp > -35 )      D_data_rx = {8'h18,16'd57195}   ;
else  if ( zb_temp <= -15 && zb_temp > -25 )      D_data_rx = {8'h18,16'd55620}   ;
else  if ( zb_temp <= -5 && zb_temp > -15  )      D_data_rx = {8'h18,16'd54044}   ;
else  if ( zb_temp <=  5 && zb_temp > -5   )      D_data_rx = {8'h18,16'd52469}   ;
else  if ( zb_temp <= 15 && zb_temp > 5  )        D_data_rx = {8'h18,16'd50894}   ;
else  if ( zb_temp <= 25 && zb_temp > 15 )        D_data_rx = {8'h18,16'd49319}   ;
else  if ( zb_temp <= 35 && zb_temp > 25 )        D_data_rx = {8'h18,16'd47744}   ;
else  if ( zb_temp <= 45 && zb_temp > 35 )        D_data_rx = {8'h18,16'd46169}   ;
else  if ( zb_temp <= 55 && zb_temp > 45 )        D_data_rx = {8'h18,16'd44594}   ;
else  if ( zb_temp <= 65 && zb_temp > 55 )        D_data_rx = {8'h18,16'd43018}   ;
else  if ( zb_temp <= 75 && zb_temp > 65 )        D_data_rx = {8'h18,16'd41443}   ;
else  if ( zb_temp <= 85 && zb_temp > 75 )       D_data_rx = {8'h18,16'd39868}   ;

end

例子1 采用了case 适合大型 输入输出一一对应的查找表

例子2采用了 if else 适合小型 区间 映射到输出的 场合

相信你已经有自己的判断了 具体是采用时序和组合电路根据 自己的应用时序需求来 ,大型稳妥一般都会延迟一拍输出,也可以设计成延迟多怕输出。

延迟多拍输出的自己要设计一下简单的时序。但都不是难事。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

我们将24小时内回复。
取消