一些Verilog的小東西

一些Verilog的小東西

常用小模塊

  1. 奇數次分頻

module fdiv5(input clk,output k_or,k1,k2);
reg [2:0] c1,c2;
reg M1,M2;

always @ (posedge clk )
    begin 
    if(c1 == 4) c1<=0 ; else c1<=c1+1;
    if(c1 == 1) M1<=~M1; else if(c1 ==3) M1<=~M1; 
    end
always @ (negedge clk )
    begin 
    if(c2 == 4) c2<=0; else c2 <=c2+1;
    if(c2 == 1)  M2<=~M2 ; else if (c2 == 3) M2<=~M2;
    end
    
assign k1 = M1; assign k2=M2;
assign k_or = k1|k2;

endmodule
  1. 未完待續

狀態機

這裏給兩種比較常見的寫法
a.

module fsm(
input x,
input rst,
input clk,

output reg [1:0] y
);
parameter state_A = 3'd0 , state_B = 3'd1 , 
			 state_C = 3'd2 , state_D = 3'd3 , 
			 state_E = 3'd4 ;
reg [2:0] state;

always @(posedge clk or posedge rst)
begin 
if(rst)
	begin
	state <= state_A;
	y	<= 2'b00;
	end
else
	case(state)
	state_A : begin
					if(!x) state <= state_B; else state <= state_C;
					y <= 2'b00;
				 end
	state_B : begin
					if(!x) state <= state_D; else state <= state_C;
					y <= 2'b00;
				 end
	state_C : begin
					if(!x) state <= state_E; else state <= state_B;
					y <= 2'b00;
				end
	state_D : begin
					if(!x) state <= state_D; else state <= state_C;
					y <= 2'b01;
				end
	state_E : begin
					if(!x) state <= state_B; else state <= state_E;
					y <= 2'b10;
				end
	default	: begin
					 state <= state_A; y <= 2'b00;
				 end
	endcase
end

endmodule

b.

module fsm2(
input [3:0] row,
input srow,
input reset,
input clk,
output reg [3:0] col
);

parameter  S0 = 3'd0 , S1 = 3'd1 , 
			  S2 = 3'd2 , S3 = 3'd3 , 
	  		  S4 = 3'd4	, S5 = 3'd5 ;

reg [3:0] current_state , next_state;

always @(posedge clk or posedge reset)
begin
	if(reset)
		current_state <= S0;
	else
		current_state <= next_state;
end

always @(*)
begin
	case(current_state)
		S0:begin
				next_state = (srow==1'b1) ? S1 : S0;
				col		  = 4'd15;
			end
		S1:begin
				next_state = (row==4'd0) ? S2 : S5;
				col		  = 4'd1;
			end
		S2:begin
				next_state =(row==4'd0) ? S3 : S5;
				col		  = 4'd2;
			end
		S3:begin
				next_state = (row==4'd0) ? S4 : S5;
				col		  = 4'd3;
			end
		S4:begin
				next_state = (row==4'd0) ? S0 : S5;
				col		  = 4'd4;
			end
		S5:begin
				next_state = S5;
				col		  = 4'd5;
			end
	endcase	
end

endmodule

懂的人自然都懂.建議用quartus寫,然後看看RTL會貼心地給出狀態描述圖

仿真的 $display $monitor $strobe的區別

  1. $display
    相當於c語言的printf,一旦程序觸發到就立即顯示

  2. $monitor
    一直以一個格式在追蹤某幾個變量或者表達式的變化

一個程序裏面只能有一個monitor在跑

  1. $strobe
    用於觀察非阻塞賦值,在所在的always塊結束後纔會改變

task 和function的區別

這裏也是給上一個功能一樣,但是分別用task和function實現的代碼

  1. task_test
module task_test(data_in,data_out); 

output reg [3:0] data_out; 
input [3:0] data_in; 

task BCD2Access3; 
output [3:0] data_out; 
input [3:0] data_in; 

    data_out = data_in + 4'd3; 
endtask 


always @(data_in) 
begin 
    if(data_in >=  4'd10) data_out = 4'b0000; 
    else  BCD2Access3(data_out,data_in); 
end 

endmodule
  1. function_test
module function_test(data_in,data_out); 

output reg [3:0] data_out; 
input [3:0] data_in; 

function BCD2Access3; 
input [3:0] data_in; 
    BCD2Access3 = data_in + 4'd3; 
endfunction 


always @(data_in) 
begin 
    if(data_in >=  4'd10) data_out = 4'b0000; 
    else  data_out = BCD2Access3(data_in); 
end 

endmodule

務必要注意兩點:
1. task可以有很多輸入輸出,但是例化的順序和task裏面寫的input,output順序是一致的,不能搞反
2. function雖說看起來很C語言,但是要注意返回值就是他的名字(,剩下的都是輸入

結語

先用來應付一下考查課,順便查漏補缺一下自己的Verilog基礎
距離 頻率計發佈到現在才4個月,最近博客的閱讀量又翻了翻…但是如果csdn再不對verilog進行markdown支持的話,就搬遷到簡書了,謝謝大家

博客不易,生活艱難

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章