一些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支持的话,就搬迁到简书了,谢谢大家

博客不易,生活艰难

猜你喜欢

转载自blog.csdn.net/weixin_38071135/article/details/91650692