组合逻辑
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