FPGA开发 verilog常用代码块

组合逻辑

always@(*)begin
    ;
end

时序逻辑 

always @(posedge CLK or posedge RST) begin
    if (RST) begin
        r_A                      <= 1'd0 ;
    end else begin
        if ( r_A ) begin
            r_A                         <= 1'd0 ;
        end else begin
            r_A                         <= 1'd1 ; 
        end
    end
end

新二段式状态机

    localparam  p_IDLE                  = 3'b001                                ;
    localparam  p_STATE1                = 3'b010                                ;
    localparam  p_CAL_DONE              = 3'b100                                ;
    
    wire                                s_STATE_IDLE                            ;
    wire                                s_STATE1                                ;
    wire                                s_STATE_CAL_DONE                        ;

    reg         [2:0]                   r_STATE                                 ;
 
    assign      s_STATE_IDLE            = r_STATE[0]                            ;
    assign      s_STATE1                = r_STATE[1]                            ;
    assign      s_STATE_CAL_DONE        = r_STATE[2]                            ;

    always@(posedge CLK or posedge RST) begin
        if(RST)
            r_STATE                     <= p_IDLE; 
        else case(r_STATE)
                 p_IDLE : begin
                    if( ) 
                        r_STATE         <= p_STATE1;
                    else
                        r_STATE         <= p_IDLE;
                end
                p_CAL_N3P6V : begin
                    if( ) 
                        r_STATE         <= p_CAL_DONE;
                     else
                        r_STATE         <= p_CAL_N3P6V;
                end
                p_STATE1 : begin
                    if( ) 
                        r_STATE         <= p_CAL_DONE;
                    else
                        r_STATE         <= p_STATE1;
                end
                p_CAL_DONE : begin
                    if( ) 
                        r_STATE         <= p_IDLE;
                    else
                        r_STATE         <= p_CAL_DONE;
                end     
                default: r_STATE <= p_IDLE;
        endcase
    end

    always@(posedge CLK or posedge RST) begin
        if(RST)
            r_V                         <= 16'd0;
        else if( s_STATE_CAL_DONE )
            r_V                         <= 16'd0 ;
        else
            r_V                         <= 16'd0;
    end

一段式状态机 

//------------<状态机参数定义>------------------------------------------
//这里使用独热码编码节省组合逻辑资源
//此外还可以使用格雷码 、二进制码
    localparam  IDLE                    = 4'b0001                               ,
                ONE                     = 4'b0010                               ,
                TWO                     = 4'b0100                               ,
                THREE                   = 4'b1000                               ;
            
//------------<reg定义:定义状态寄存器>----------------------------------
    reg         [3:0]                   r_state                                 ;
 
//-----------------------------------------------------------------------
//--    1段式状态机(Moore)
//-----------------------------------------------------------------------
    always@(posedge CLK or posedge RST)begin
        if (RST) begin
            cola <= 1'b0;               //复位初始状态
            r_state <= IDLE;
        end else begin
            case(r_state)               //根据当前状态、输入进行状态转换判断
                                        //根据当前状态进行输出
                IDLE:begin
                    cola <= 1'b0;       //初始状态无可乐输出
                    if(money)               
                        r_state <= ONE; //投币1元则状态跳转到ONE
                    else
                        r_state <= IDLE;    //否则保持原有状态
                end             
                ONE:begin
                    cola <= 1'b0;       //该状态只有1元,无可乐输出
                    if(money)
                        r_state <= TWO; //投币1元则状态跳转到TWO
                    else
                        r_state <= ONE; //否则保持原有状态
                end
                TWO:begin
                    cola <= 1'b0;       //该状态只有2元,无可乐输出
                    if(money)
                        r_state <= THREE;   //投币1元则状态跳转到THREE
                    else
                        r_state <= TWO; //否则保持原有状态
                end 
                THREE:begin
                    cola <= 1'b1;       //该状态有3元,有可乐输出
                                        //但是时序逻辑输出会落后一个时钟周期
                    if(money)
                        r_state <= ONE; //投币1元则状态跳转到ONE
                    else
                        r_state <= IDLE;    //否则状态跳转到IDLE
                end         
                default:begin           //默认状态同IDLE
                    cola <= 1'b0;
                    if(money)
                        r_state <= ONE;
                    else
                        r_state <= IDLE;
                end 
            endcase
        end
    end

二段式状态机

//------------<状态机参数定义>------------------------------------------
    localparam  IDLE                    = 4'b0001                               ,
                ONE                     = 4'b0010                               ,
                TWO                     = 4'b0100                               ,
                THREE                   = 4'b1000                               ;
//------------<reg定义>定义现态寄存器-------------------------------------------------
//------------<reg定义>定义次态寄存器-------------------------------------------------
    reg         [3:0]                   r_CUR_STATE                             ;               
    reg         [3:0]                   r_NEXT_STATE                            ;               
 
//-----------------------------------------------------------------------
//--状态机第一段:同步时序描述状态转移
//-----------------------------------------------------------------------
    always@(posedge CLK or posedge RST)begin
        if(RST)
            r_CUR_STATE                 <= p_IDLE                               ;   //复位初始状态
        else
            r_CUR_STATE                 <= r_NEXT_STATE                         ;   //次态转移到现态
    end 
 
//-----------------------------------------------------------------------
//--状态机第二段:组合逻辑判断状态转移条件,描述状态转移规律以及输出
//-----------------------------------------------------------------------
    always@(*)begin                     //组合逻辑
        case(cur_state)                 //根据当前状态、输入进行状态转换判断
                                        //根据当前状态进行输出
            IDLE:begin
                cola = 1'b0;            //初始状态无可乐输出
                if(money)               //投币1元
                    next_state = ONE;   //次态(下个状态)为ONE      
                else 
                    next_state = IDLE;  //次态为现态 
            end                 
            ONE:begin
                cola = 1'b0;            //无可乐输出
                if(money)               //投币1元
                    next_state = TWO;   //次态(下个状态)为TWO
                else 
                    next_state = ONE;   //次态为现态         
            end
            TWO:begin                   
                cola = 1'b0;            //无可乐输出
                if(money)               //投币1元
                    next_state = THREE; //次态(下个状态)为THREE
                else                                
                    next_state = TWO;   //次态为现态
            end 
            THREE:begin 
                cola = 1'b1;            //输出可乐输出
                if(money)               //投币1元
                    next_state = ONE;   //次态(下个状态)为ONE      
                else                                
                    next_state = IDLE;  //次态为IDLE
            end
            default:begin               //默认状态同IDLE
                cola = 1'b0;        
                if(money)
                    next_state = ONE;
                else 
                    next_state = IDLE;
            end 
        endcase
    end

三段式状态机

//------------<状态机参数定义>------------------------------------------
	localparam	IDLE  					= 3'b0001								,
				ONE   					= 3'b0010								,
				TWO   					= 3'b0100								;
			
//------------<reg定义>-------------------------------------------------
	reg			[3:0]					cur_state								;					
	reg			[3:0]					next_state								;					
//-----------------------------------------------------------------------
//--状态机第一段:同步时序描述状态转移
//-----------------------------------------------------------------------
	always@(posedge CLK or posedge RST)begin
		if(RST)
			cur_state <= IDLE;				//复位初始状态
		else
			cur_state <= next_state;		//次态转移到现态
	end
//-----------------------------------------------------------------------
//--状态机第二段:组合逻辑判断状态转移条件,描述状态转移规律以及输出
//-----------------------------------------------------------------------
	always@(*)begin
		case(cur_state)						//组合逻辑
											//根据当前状态、输入进行状态转换判断										
			IDLE:begin				
				if(money)					
					next_state = ONE;		//投币1元,则状态转移到ONE
				else 
					next_state = IDLE;		//没有投币,则状态保持	
			end					
			ONE:begin				
				if(money)
					next_state = TWO;		//投币1元,则状态转移到TWO
				else 
					next_state = ONE;		//没有投币,则状态保持
			end
			TWO:begin				
				if(money)
					next_state = IDLE;		//投币1元,则状态转移到IDLE
				else                        
					next_state = TWO;       //没有投币,则状态保持
			end	
			default:begin					//默认状态同IDLE
				if(money)
					next_state = ONE;
				else 
					next_state = IDLE;	
			end
		endcase
	end
//-----------------------------------------------------------------------
//--状态机第三段:时序逻辑描述输出
//-----------------------------------------------------------------------
	always@(posedge sys_clk or posedge sys_rst_n)begin
		if(!sys_rst_n)
			cola <= 1'b0;					//复位、初始状态 
		else
			case(cur_state)					//根据当前状态进行输出
				IDLE:	cola <= 1'b0;		//无可乐输出(因为输入不管是0、1都是输出0,所以省略写法)			
				ONE:	cola <= 1'b0;		//无可乐输出(因为输入不管是0、1都是输出0,所以省略写法)	
				TWO:begin					
					if(money)
						cola <= 1'b1;		//如果输入1,则输出可乐
					else
						cola <= 1'b0;		//如果输入0,则无可乐输出
				end
				default:cola <= 1'b0;		//默认无可乐输出
			endcase
	end

 锁存信号

reg         [2:0]                   r_LCH                                   ;

always @(posedge CLK or posedge RST) begin
    if (RST) begin
        r_LCH                       <= 3'd0 ;
    end else if ( r_FLAG1 ) begin
        r_LCH                       <= r_XXX1;
    end else if ( r_FLAG2 ) begin
        r_LCH                       <= r_XXX2;
    end
end 

取下降沿

    reg         [1:0]                   r_SET_NEG                               ;           
    reg                                 r_SET_NEG_FLAG                          ;           
    always@(posedge CLK or posedge RST)begin
        if(RST)begin
            r_SET_NEG                   <= 2'd0;
        end else begin
            r_SET_NEG                   <= { r_SET_NEG[0], SET};
        end
    end
    always@(posedge CLK or posedge RST)begin
        if(RST)begin
            r_SET_NEG_FLAG              <= 1'd0;
        end else if (r_SET_NEG  == 2'b10) begin
            r_SET_NEG_FLAG              <= 1'd1;
        end else begin
            r_SET_NEG_FLAG              <= 1'd0;
        end
    end

取上升沿

    reg         [1:0]                   HDC_CODE_POS                            ;               
    reg                                 i_HDC_T_VLD                             ;               
    always@(posedge CLK or posedge RST)begin
        if(RST)begin
            HDC_CODE_POS                <= 2'd0;
        end else begin
            HDC_CODE_POS                <= { HDC_CODE_POS[0], CLK_200HZ};
        end
    end
    always@(posedge CLK or posedge RST)begin
        if(RST)begin
            i_HDC_T_VLD                 <= 1'd0;
        end else if (HDC_CODE_POS  == 2'b01) begin
            i_HDC_T_VLD                 <= 1'd1;
        end else begin
            i_HDC_T_VLD                 <= 1'd0;
        end
    end

function语句

function    [3:0] out0;  
        input   [7:0]                   x;
        reg     [3:0]       count;
        integer i;
        begin
            count=0;
            for(i=0;i<=7;i=i+1)
                if( x[i]==1’b0 )	 count=count+1;
            out0=count;
        end
    endfunction
    
    always @(posedge CLK or posedge RST) begin
        if (RST) begin
            r_DLY                       <= 4'd0 ;
        end else begin
            r_DLY                       <= out0;
        end
    end

    //每当地址未发生变化,重新计算偶校验位
    always @(addr) begin
        parity=cal_parity(addr);
        \$display("parity calculated = %b",cal_paraty(addr));
    end

    //定义偶检验函数
    function cal_parity;
        input [31:0]address;
        begin
        cal_parity=^address;
        end
    endfunction

generate语句

    genvar I    ;
    generate
    for (I=0 ; I<16 ; I=I+1) begin : CTRL    
    CTRL U_CTRL (
        .SYS_RST                        ( s_SYS_RST                             ),//
        .SYS_CLK                        ( s_CLK_100M                            ),//
        .REG_FDO_INIT                   ( s_REG_FDO_INIT[I]                     )//
    );
    end
    endgenerate 

配置inout引脚或三态门

    wire        DQ;
    reg         FLAG = 1'b0 ;  

    initial begin 
        #555300 FLAG = 1'b1 ;
        #120340 FLAG = 1'b0 ;
    end

    assign      DQ  = FLAG ? 1'b0 : 1'bz ;

task

    task sig_input ;
        input   [3:0]                   a   ;
        input   [3:0]                   b   ;
        output  [3:0]                   ao  ;
        output  [3:0]                   bo  ;
        @(posedge clk) ;
            ao  = a ;
            bo  = b ;
    endtask ; 

    
    initial begin
        a         = 0 ;
        b         = 0 ;
        sig_input(4'b1111, 4'b1001, a, b);
        sig_input(4'b0110, 4'b1001, a, b);
        sig_input(4'b1000, 4'b1001, a, b);
    end

case语句(组合逻辑)

    localparam  RANGE_3              = 4'b0011                               ;
    localparam  RANGE_1              = 4'b0010                               ;
    localparam  RANGE_2              = 4'b0000                               ;
    localparam  RANGE_4              = 4'b1110                               ;
    localparam  RANGE_8              = 4'b1110                               ;


    always@(*) begin                        
        case(V_RANGE)                                       
            RANGE_3:begin
                r_V_RANGE               = {5'b00001} ;
            end                 
            RANGE_1:begin
                r_V_RANGE               = {5'b00010} ;
                r_R_V_RANGE             = 4'd1 ;
            end
            default:begin               
                r_V_RANGE               = {5'b00100} ;
            end     
        endcase
    end

计数器CNT

reg         [18:0]                  r_CNT                                   ;
always @(posedge CLK or posedge RST) begin
    if (RST) begin
        r_CNT                   <= 19'd0 ;
    end else if ( r_CNT == 19'd0) begin
        r_CNT                   <= 19'd0 ;
    end else begin
        r_CNT                   <= r_CNT + 1'd1 ;
    end
end

打拍DLY

reg                                 r_DLY                                   ;

always @(posedge CLK or posedge RST) begin
    if (RST) begin
        r_DLY                <= 1'd0 ;
    end else begin
        r_DLY                       <= r_xxx;
    end
end

产生脉冲

reg                                 r_PLUSE                                 ;

always @(posedge CLK or posedge RST) begin
    if (RST) begin
        r_PLUSE              <= 1'd0 ;
    end else if (r_flag)  begin
        r_PLUSE                     <= 1'd1 ;
    end else begin
        r_PLUSE                     <= 1'd0 ;
    end
end

modelsim仿真语句


write format wave -window .main_pane.wave.interior.cs.body.pw.wf D:sim/wave.do
vlib work
vmap work
##
vlog -reportprogress 300 -incr  -work work	../rtl/*.v
vlog -reportprogress 300 -incr  -work work	../rtl/tb/tb_TOP02.v
##ip
vlog -reportprogress 300 -incr  -work work	../rtl/al_ip/*.v

vcom                            -work work					../RTL/main.vhd   编译vhdl 文件

vsim -gui -L D:/modeltech64_10.7/Anlogic/a13_10_ver -voptargs=+acc work.tb_TOP
set NumericStdNoWarnings 1
set StdArithNoWarnings   1
do wave.do

run 1ms
force -freeze sim:/tb_TOP/u_TOP/U02_RT_POWER_TEMP_CH1/U02_ACQ_CAL_POWER/i_DATA_CONVERT_VLD 1'h0 0
run 10026ns
noforce sim:/tb_TOP/u_TOP/U02_RT_POWER_TEMP_CH1/U02_ACQ_CAL_POWER/i_DATA_CONVERT_VLD
run 1ms

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用纯Verilog代码实现FPGA上的图像缩放。下面是一个简单的示例,展示了如何使用双线性插值算法进行图像缩放: ```verilog module image_scale ( input wire clk, input wire rst, input wire [7:0] in_width, input wire [7:0] in_height, input wire [7:0] out_width, input wire [7:0] out_height, input wire [15:0] in_image [0:1023][0:767], output wire [15:0] out_image [0:511][0:383] ); // 计算水平和垂直比例因子 reg [15:0] scale_x; reg [15:0] scale_y; always @(in_width, out_width) begin scale_x = (in_width << 16) / (out_width + 1); end always @(in_height, out_height) begin scale_y = (in_height << 16) / (out_height + 1); end // 缩放图像 always @(posedge clk or posedge rst) begin if (rst) begin // 复位状态 // ... end else begin // 缩放计算 // ... end end endmodule ``` 在上面的示例中,`in_width`和`in_height`表示输入图像的宽度和高度,`out_width`和`out_height`表示期望的输出图像的宽度和高度。`in_image`是一个二维数组,用于存储输入图像的像素值。`out_image`也是一个二维数组,用于存储输出图像的像素值。 你需要在`always @(posedge clk or posedge rst)`块中实现图像缩放的逻辑。你可以使用双线性插值算法来计算输出图像的每个像素值。具体的实现方法超出了本文的范围,但你可以参考相关资料来了解如何在Verilog中实现双线性插值算法。 请注意,上述代码仅提供了一个基本的框架,你需要根据实际需求进行适当的修改和完善。同时,你还需要根据你使用的开发板和FPGA器件进行相应的时钟和复位处理。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值