RTL代码转成的电路是什么样的?

  • Post author:
  • Post category:其他


常见的RTL代码布局布线时转成的电路是什么样的?因为不知道实际电路直接写代码可以实现功能,却不一定是节省面积的写法,因此,我想花些功夫去看一下代码转成的电路,希望有助于加深理解。


模块一

:一个计数模块,复位清零,计到6清零

	always @(posedge Clk or negedge Rst_n) begin
		if (!Rst_n) begin
			Clk_cnt <= 3'd0;
		end
		else if (Clk_cnt == 3'd6) begin
			Clk_cnt <= 3'd0;
		end
		else begin
			Clk_cnt <= Clk_cnt + 1'b1;
		end
	end

观察到三个触发器,时钟和清零很好理解,三个触发器的输入分别是三个LUT的输出,三个LUT都是三输入LUT,三个输入分别连的三个触发器的输出。

写出状态转移表就明白了

初态Q1 Q2 Q3 次态 Q1* Q2* Q3*
000 001
001 010
010 011

011

100
100 101
101 110
110 000

也就是说,下一个输入取决于上一个输出的状态,如,当Q1=0,Q2=0,Q3=0时,Q1*=0,所以将Q1Q2Q3作为LUT的输入,当三个都为0时,LUT输出0,并送到Q1。Q2Q3类似。

当位数变多,超出器件的单个LUT输入端时,会在LUT前级联一个LUT,以扩展输入,如我的器件中LUT是6输入的,当我的位数有9位时,我需要9输入的LUT,此时会用6输入LUT的其中一个输入连一个4输入的LUT,这样就能做到9输入LUT。


模块二

:一个判断条件,判断某个变量值为多少时进行寄存器数据变化,

	always @ ( posedge Clk  or negedge Rst_n) begin
		if ( !Rst_n )
			scl_r <= 1'b1;
		else if(Clk_cnt == 9'd3 || Clk_cnt == 9'd2)
			scl_r <= ~scl_r;
		else
			scl_r <= scl_r;		
	end
	
	always @(posedge Clk or negedge Rst_n) begin
		if (!Rst_n) begin
			Clk_cnt <= 8'd0;
		end
		else if (Clk_cnt == 8'd5) begin
			Clk_cnt <= 8'd0;
		end
		else begin
			Clk_cnt <= Clk_cnt + 1'b1;
		end
	end

同样也是列出真值表,当值为某个值时令输出变化,由于此处变化为对原来值取反,所以将寄存器输入也送入LUT共同参与输出值的决定(图中蓝线)


模块三

:状态机

module state_mechine(
	input Clk,
	input Rst_n,
	output reg data_o1,
	output reg data_o2
 );

parameter  
	STATE1  =0,   
	STATE2  =1, 
	STATE3  =2;  

 reg  [2:0] Clk_cnt;
 reg  [1:0] cstate;
 reg  [1:0] nstate;

 always @(posedge Clk or negedge Rst_n) begin
 	if (!Rst_n)
 		Clk_cnt <= 9'd0;
 	else if (Clk_cnt == 9'd4)
 		Clk_cnt <= 9'd0;
 	else
 		Clk_cnt <= Clk_cnt + 1'b1;
 end

//------------------------状态机------------------------------//
 always @ ( posedge Clk or negedge Rst_n) begin
	if ( !Rst_n )
		cstate <= STATE1;
	else
		cstate <= nstate;
 end
 
 always @ ( * ) begin
	nstate = STATE1;
	case (cstate)
		STATE1:begin
			if(Clk_cnt == 9'd4)
				nstate = STATE2;
			else
				nstate = STATE1;
   		end
   		STATE2:begin
   			if (Clk_cnt == 9'd4)
   				nstate = STATE3 ;
   			else
   				nstate = STATE2;
   		 end
		
   		STATE3 :begin
   		  	if (Clk_cnt == 9'd4)
   		   		nstate = STATE1;
   		  	else
   		   		nstate = STATE3 ;
   		 	end
   		endcase
    end

always @ ( posedge Clk or negedge Rst_n) begin
	if ( !Rst_n )begin
		data_o1 <= 1'b0;
		data_o2 <= 1'b0;
	end
	else begin
		case(cstate) 
			STATE1:begin
				data_o1	<= 1'b0;
				data_o2 <= 1'b1;
			end
			STATE2:	begin
				data_o1	<= 1'b0;
				if (Clk_cnt == 9'd2)
					data_o2 <= 0;
				else
					data_o2 <= 1;
			end
			STATE3:begin
				data_o1	<= 1'b1;
				if(Clk_cnt == 9'd2)
					data_o2 <= 1;
				else
					data_o2 <= 0;
			end
		endcase
	end
end
endmodule

对于cstate和nstate,其输出取决于状态和clk_cnt,因此,其前的LUT连着状态和clk_cnt。data_o1和data_o2同理。


模块四

:移位寄存器

 always @(posedge Clk or negedge Rst_n) begin
 	if (!Rst_n)
 		addr <= 4'b1001;
 	else begin
 		data_o <= addr[0];
 		addr <= addr >> 1;
 	end
 end

上面的LUT可以看到真值表,就是不知道为什么和我自己化简的不一样,所以对于为什么有时候可以少一两个输入还不太明白。



版权声明:本文为sinat_34245317原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。