一、顶层设计
button_in_out模块是对按键做去抖动
DUT模块内有信号激励stimulus,触发strigger,状态机timebase
二、模块代码
1、stimulus模块
输入:时钟I_CLK,归零I_RST,位宽I_N_CLKNUM(=3),增量I_INC=(111000H)产生信号的类型I_MODE(=1表示DDS电路产生正弦信号)
输出:数据O_DOUT,使能/溢出O_DOV
module stimulus( I_CLK , // clock, posedge valid I_RST , // reset, high level reset I_N_CLKNUM , // N_CLKNUM >= 1, every N_CLKNUM period output 1 data sample I_N_INC , // counter increase value or dds phase increase word I_MODE , // 0 : counter, 1: DDS O_DOUT , // data output O_DOV ); // data output valid parameter FW_WL = 32; // frequency word word length in bit parameter RA_WL = 10; // rom address word length in bit parameter RD_WL = 8; // rom data word word length in bit input I_CLK ; input I_RST ; input [FW_WL -1:0] I_N_CLKNUM; input [FW_WL -1:0] I_N_INC ; input I_MODE ; output[RD_WL -1:0] O_DOUT ; output O_DOV ; wire [FW_WL -1:0] cnt_max_W; reg [FW_WL -1:0] clk_cnt_R; reg [FW_WL -1:0] acc_cnt_R; reg work_en_W, work_en_W_R1, work_en_W_R2; wire [RA_WL -1:0] addr_W ; wire [RD_WL -1:0] romout_W ; reg [RA_WL -1:0] addr_W_R1 ; reg [RD_WL -1:0] O_DOUT ; reg O_DOV ; assign cnt_max_W = I_N_CLKNUM -1; // pipeline design // work_en_W | acc_cnt_R | romout_W | O_DOUT // | addr_W | addr_W_R1 | // | work_en_W_R1 | work_en_W_R2 | O_DOV // update work cycle counter always @ (posedge I_CLK or posedge I_RST) begin if(I_RST) begin clk_cnt_R <= 0; end else begin if(clk_cnt_R < cnt_max_W) begin clk_cnt_R <= clk_cnt_R + 1'b1; end // if else begin clk_cnt_R <= 0; end // else clk_cnt_R end // else RST end // always // generate work cycle enable always @ (*) begin if(clk_cnt_R == cnt_max_W) begin work_en_W = 1'b1; end else begin work_en_W = 1'b0; end end // update acc always @ (posedge I_CLK or posedge I_RST) begin if(I_RST) begin acc_cnt_R <= 0; end else begin if(work_en_W) begin acc_cnt_R <= acc_cnt_R + I_N_INC; end end end // get addr wire assign addr_W = acc_cnt_R[FW_WL -1: FW_WL -1-RA_WL +1]; DDS_CORE_ROM u_sinrom( .CLK (I_CLK ), // clock .RA (addr_W ), // read address .RD (romout_W )); // read data always @ (posedge I_CLK ) begin addr_W_R1 <= addr_W; work_en_W_R1 <= work_en_W ; work_en_W_R2 <= work_en_W_R1; if(I_MODE == 0)begin // mode == 0, counter O_DOUT <= addr_W_R1[RD_WL-1:0]; end else begin O_DOUT <= {{~romout_W[RD_WL-1]},{romout_W[RD_WL-2:0]}} ; // signed 2's complement code to unsigned code end O_DOV <= work_en_W_R2; end endmodule // module dds_core
2、trigger
输入:触发电平的区间I_TRIG_V_MAX,I_TRIG_V_MIN,触发模式I_T_MODE(00表示自由触发;01表示上升沿触发;10表示下降沿触发;11表示双向触发)
输出:O_TRIG_ON表示开始触发
触发方式:
自由触发=李萨如波形
上升沿触发:达到电平区间且在上升沿
module trigger( I_CLK , // clock, posedge valid I_RST , // reset, high level reset I_DIN , I_DEN , I_TRIG_V_MAX , // trigger range max value I_TRIG_V_MIN , // trigger range min value I_T_MODE , // trigger mode 00 free trig , 01 value inc trig, 10 value dec trig, 11 value trig both inc or dec O_DOUT , O_DOV , O_TRIG_ON ); parameter DWL = 8; localparam DMAX = (1 << DWL) - 1; input I_CLK ; input I_RST ; input [DWL-1:0] I_DIN ; input I_DEN ; input [2-1:0] I_T_MODE ; input [DWL-1:0] I_TRIG_V_MAX ; input [DWL-1:0] I_TRIG_V_MIN ; output [DWL-1:0] O_DOUT ; output O_DOV ; output O_TRIG_ON ; reg [DWL-1:0] din_Z1R ; // previous din reg [DWL-1:0] din_d1R, din_d2R, din_Z1d1R ; reg den_d1R, den_d2R ; reg [DWL-1:0] t_v_max_R, t_v_min_R; reg W_trig_on; reg W_in_trig_range, W_din_increase, W_din_decrease; reg O_TRIG_ON; assign O_DOUT = din_d2R; assign O_DOV = den_d2R; // pipeline design // I_DIN | din_d1R, din_Z1d1R | din_d2R // I_DEN | den_d1R | den_d2R // | W_in_trig_range | O_DOUT // | W_din_increase | O_DOV // | W_din_decrease | O_TRIG_ON // | W_trig_on | always @ (posedge I_CLK ) begin t_v_max_R <= I_TRIG_V_MAX ; t_v_min_R <= I_TRIG_V_MIN ; din_d1R <= I_DIN; den_d1R <= I_DEN; din_d2R <= din_d1R; den_d2R <= den_d1R; O_TRIG_ON <= W_trig_on; din_Z1d1R <= din_Z1R; if(I_DEN) din_Z1R <= I_DIN; end // always always @ (*) begin if((din_d1R >= t_v_min_R) && (din_d1R <= t_v_max_R)) begin W_in_trig_range = 1'b1; end else begin W_in_trig_range = 1'b0; end if(din_d1R > din_Z1d1R) W_din_increase = 1'b1; else W_din_increase = 1'b0; if(din_d1R < din_Z1d1R) W_din_decrease = 1'b1; else W_din_decrease = 1'b0; // trigger mode 00 free trig , 01 value inc trig, 10 value dec trig, 11 value trig both inc or dec case (I_T_MODE) 2'b00: begin W_trig_on = 1'b1; end 2'b01: begin W_trig_on = (W_din_increase && W_in_trig_range); end 2'b10: begin W_trig_on = (W_din_decrease && W_in_trig_range); end 2'b11: begin W_trig_on = (den_d1R && W_in_trig_range) ; end endcase end // always endmodule // module
3、timebase
产生触发后开始存储数据,根据START,TRIG_ON,RAM_FULL信号形成状态机
三、signaltap波形
在START上升沿时开始检测触发,产生触发后,产生地址信号把波形数据存储到RAM,存储到RAM后产生RAM_FULL信号,告知单片机可以读取RAM了