From 1e9d7b7680b7b70b2387ae6b7e1ca814cdecc79f Mon Sep 17 00:00:00 2001 From: Jojojoppe Date: Sun, 5 Oct 2025 23:42:51 +0200 Subject: [PATCH] Got rid of ftw_we and tested on hw with freq sweep --- rtl/core/nco_q15.v | 48 ++++++++++++++++++-------------------- rtl/toplevel/top_generic.v | 32 +++++++++++++++++++++---- sim/tb/tb_nco_q15.v | 9 ++----- 3 files changed, 52 insertions(+), 37 deletions(-) diff --git a/rtl/core/nco_q15.v b/rtl/core/nco_q15.v index 0f11ee6..9c06e69 100644 --- a/rtl/core/nco_q15.v +++ b/rtl/core/nco_q15.v @@ -23,7 +23,6 @@ module nco_q15 # // Frequency control input wire [31:0] ftw_in, // Frequency Tuning Word (FTW) - input wire ftw_we, // write-enable strobe (1 clk pulse) // Outputs (valid on clk_en rising pulse, i.e., at FS_HZ) output reg signed [15:0] sin_q15, // signed Q1.15 sine @@ -48,7 +47,7 @@ module nco_q15 # // If you prefer, replace 16 with $clog2(DIV) on a tool that supports it well. reg [15:0] tick_cnt; - always @(posedge clk or negedge rst_n) begin + always @(posedge clk) begin if (!rst_n) begin tick_cnt <= 16'd0; clk_en <= 1'b0; @@ -65,12 +64,11 @@ module nco_q15 # // ========================================================== // Frequency control register - // - You present ftw_in and pulse ftw_we (1 clk) to update. + // - You present ftw_in // ========================================================== reg [31:0] ftw; - always @(posedge clk or negedge rst_n) begin - if (!rst_n) ftw <= ftw_from_hz(1000, PHASE_BITS, FS_HZ); // Start at 1khz - else if (ftw_we) ftw <= ftw_in; + always @(posedge clk) begin + ftw <= ftw_in; end // ========================================================== @@ -82,7 +80,7 @@ module nco_q15 # reg [PHASE_BITS-1:0] phase_sin, phase_cos; wire [PHASE_BITS-1:0] phase_cos_plus90 = phase_sin + ({{(PHASE_BITS-2){1'b0}}, 2'b01} << (PHASE_BITS-2)); // +90° - always @(posedge clk or negedge rst_n) begin + always @(posedge clk) begin if (!rst_n) begin phase_sin <= {PHASE_BITS{1'b0}}; phase_cos <= {PHASE_BITS{1'b0}}; @@ -132,11 +130,11 @@ module nco_q15 # // ========================================================== // Output registers (update on clk_en) // ========================================================== - always @(posedge clk or negedge rst_n) begin + always @(posedge clk) begin if (!rst_n) begin sin_q15 <= 16'sd0; cos_q15 <= 16'sd0; - end else if (clk_en) begin + end else begin sin_q15 <= sin_q15_next; cos_q15 <= cos_q15_next; end @@ -154,22 +152,22 @@ module sine_qtr_lut64( ); always @* begin case (addr) -6'd0: dout = 8'd0; 6'd1: dout = 8'd6; 6'd2: dout = 8'd13; 6'd3: dout = 8'd19; -6'd4: dout = 8'd25; 6'd5: dout = 8'd31; 6'd6: dout = 8'd37; 6'd7: dout = 8'd44; -6'd8: dout = 8'd50; 6'd9: dout = 8'd56; 6'd10: dout = 8'd62; 6'd11: dout = 8'd68; -6'd12: dout = 8'd74; 6'd13: dout = 8'd80; 6'd14: dout = 8'd86; 6'd15: dout = 8'd92; -6'd16: dout = 8'd98; 6'd17: dout = 8'd103; 6'd18: dout = 8'd109; 6'd19: dout = 8'd115; -6'd20: dout = 8'd120; 6'd21: dout = 8'd126; 6'd22: dout = 8'd131; 6'd23: dout = 8'd136; -6'd24: dout = 8'd142; 6'd25: dout = 8'd147; 6'd26: dout = 8'd152; 6'd27: dout = 8'd157; -6'd28: dout = 8'd162; 6'd29: dout = 8'd167; 6'd30: dout = 8'd171; 6'd31: dout = 8'd176; -6'd32: dout = 8'd180; 6'd33: dout = 8'd185; 6'd34: dout = 8'd189; 6'd35: dout = 8'd193; -6'd36: dout = 8'd197; 6'd37: dout = 8'd201; 6'd38: dout = 8'd205; 6'd39: dout = 8'd208; -6'd40: dout = 8'd212; 6'd41: dout = 8'd215; 6'd42: dout = 8'd219; 6'd43: dout = 8'd222; -6'd44: dout = 8'd225; 6'd45: dout = 8'd228; 6'd46: dout = 8'd231; 6'd47: dout = 8'd233; -6'd48: dout = 8'd236; 6'd49: dout = 8'd238; 6'd50: dout = 8'd240; 6'd51: dout = 8'd242; -6'd52: dout = 8'd244; 6'd53: dout = 8'd246; 6'd54: dout = 8'd247; 6'd55: dout = 8'd249; -6'd56: dout = 8'd250; 6'd57: dout = 8'd251; 6'd58: dout = 8'd252; 6'd59: dout = 8'd253; -6'd60: dout = 8'd254; 6'd61: dout = 8'd254; 6'd62: dout = 8'd255; 6'd63: dout = 8'd255; + 6'd0: dout = 8'd0; 6'd1: dout = 8'd6; 6'd2: dout = 8'd13; 6'd3: dout = 8'd19; + 6'd4: dout = 8'd25; 6'd5: dout = 8'd31; 6'd6: dout = 8'd37; 6'd7: dout = 8'd44; + 6'd8: dout = 8'd50; 6'd9: dout = 8'd56; 6'd10: dout = 8'd62; 6'd11: dout = 8'd68; + 6'd12: dout = 8'd74; 6'd13: dout = 8'd80; 6'd14: dout = 8'd86; 6'd15: dout = 8'd92; + 6'd16: dout = 8'd98; 6'd17: dout = 8'd103; 6'd18: dout = 8'd109; 6'd19: dout = 8'd115; + 6'd20: dout = 8'd120; 6'd21: dout = 8'd126; 6'd22: dout = 8'd131; 6'd23: dout = 8'd136; + 6'd24: dout = 8'd142; 6'd25: dout = 8'd147; 6'd26: dout = 8'd152; 6'd27: dout = 8'd157; + 6'd28: dout = 8'd162; 6'd29: dout = 8'd167; 6'd30: dout = 8'd171; 6'd31: dout = 8'd176; + 6'd32: dout = 8'd180; 6'd33: dout = 8'd185; 6'd34: dout = 8'd189; 6'd35: dout = 8'd193; + 6'd36: dout = 8'd197; 6'd37: dout = 8'd201; 6'd38: dout = 8'd205; 6'd39: dout = 8'd208; + 6'd40: dout = 8'd212; 6'd41: dout = 8'd215; 6'd42: dout = 8'd219; 6'd43: dout = 8'd222; + 6'd44: dout = 8'd225; 6'd45: dout = 8'd228; 6'd46: dout = 8'd231; 6'd47: dout = 8'd233; + 6'd48: dout = 8'd236; 6'd49: dout = 8'd238; 6'd50: dout = 8'd240; 6'd51: dout = 8'd242; + 6'd52: dout = 8'd244; 6'd53: dout = 8'd246; 6'd54: dout = 8'd247; 6'd55: dout = 8'd249; + 6'd56: dout = 8'd250; 6'd57: dout = 8'd251; 6'd58: dout = 8'd252; 6'd59: dout = 8'd253; + 6'd60: dout = 8'd254; 6'd61: dout = 8'd254; 6'd62: dout = 8'd255; 6'd63: dout = 8'd255; default: dout=8'd0; endcase end diff --git a/rtl/toplevel/top_generic.v b/rtl/toplevel/top_generic.v index 2ab9ce0..822cffc 100644 --- a/rtl/toplevel/top_generic.v +++ b/rtl/toplevel/top_generic.v @@ -15,16 +15,38 @@ module top_generic( assign led_green = 1'b0; assign led_red = 1'b0; + + reg [11:0] count; + localparam integer DIV_MAX = 100_000 - 1; // 1 ms tick at 100 MHz + reg [16:0] div_counter = 0; // enough bits for 100k (2^17=131072) + always @(posedge aclk) begin + if (!aresetn) begin + div_counter <= 0; + count <= 0; + end else begin + if (div_counter == DIV_MAX) begin + div_counter <= 0; + if (count == 12'd3999) + count <= 0; // wrap at 4000 + else + count <= count + 1'b1; // increment every 1 ms + end else begin + div_counter <= div_counter + 1'b1; + end + end + end + + wire [15:0] sin_q15; wire clk_en; nco_q15 #( .CLK_HZ(100_000_000), - .PHASE_BITS(16) + .PHASE_BITS(16), + .FS_HZ(40_000) ) nco ( .clk (aclk), .rst_n (aresetn), - .ftw_in (32'h0), - .ftw_we (1'b0), + .ftw_in (ftw_from_hz(count, 16, 40_000)), .sin_q15(sin_q15), .cos_q15(), .clk_en (clk_en) @@ -37,9 +59,9 @@ module top_generic( wire [5:0] dac_code_next = biased[15:10]; // 0..63 (MSB=bit5) // Register it at the sample rate (clk_en) reg [5:0] dac_code; - always @(posedge aclk or negedge aresetn) begin + always @(posedge aclk) begin if (!aresetn) dac_code <= 6'd0; - else if (clk_en) dac_code <= dac_code_next; + else dac_code <= dac_code_next; end assign r2r = dac_code; endmodule diff --git a/sim/tb/tb_nco_q15.v b/sim/tb/tb_nco_q15.v index 27d9094..d5ae656 100644 --- a/sim/tb/tb_nco_q15.v +++ b/sim/tb/tb_nco_q15.v @@ -21,7 +21,6 @@ module tb_nco_q15(); reg [31:0] ftw_in; - reg ftw_we; wire [15:0] sin_q15; wire [15:0] cos_q15; wire out_en; @@ -30,7 +29,6 @@ module tb_nco_q15(); .clk (clk), .rst_n (resetn), .ftw_in (ftw_in), - .ftw_we (ftw_we), .sin_q15(sin_q15), .cos_q15(cos_q15), .clk_en (out_en) @@ -38,13 +36,10 @@ module tb_nco_q15(); initial begin ftw_in = 32'h0; - ftw_we = 1'b0; #100 - @(posedge clk); ftw_in = ftw_from_hz(1000, 16, 40000); - ftw_we = 1'b1; - @(posedge clk); - ftw_we = 1'b0; + #2_500_000 + ftw_in = ftw_from_hz(2000, 16, 40000); end; endmodule \ No newline at end of file