diff --git a/HDL/sdmod.sv b/HDL/sdmod.sv new file mode 100644 index 0000000..2993bec --- /dev/null +++ b/HDL/sdmod.sv @@ -0,0 +1,23 @@ +module sdmod ( + input signed [7:0] val, + input clk, + input reset, + output daco +); + +logic out; +logic signed [7:0] eps; +logic signed [7:0] un; + +always_ff @(posedge clk, negedge reset) begin + if (~reset) begin + un <= 8'd0; + end else begin + un <= val - eps; + end +end + +assign daco = (un >= $signed(8'd0)) ? 1'd1 : 1'd0; +assign eps = (un >= $signed(8'd0)) ? $signed(8'd126) - un : $signed(-8'd126) - un; + +endmodule diff --git a/HDL/sigdel.sv b/HDL/sigdel.sv index 19ae48f..5acf7e3 100644 --- a/HDL/sigdel.sv +++ b/HDL/sigdel.sv @@ -11,11 +11,27 @@ module sigdel output logic fout ); + logic [7:0] phinc_val, phase, sine; + + //control slave logic + always_ff @ (posedge clk or negedge clr_n) begin + if (!clr_n) begin + phinc_val[7:0] <= 8'd0; + end else begin + if (!wr_n) begin + phinc_val[7:0] <= wr_data[31:0]; + end + end + end + phacc phacc_inst (.phinc(phinc_val), .clk(clk), .reset(clr_n), .phase(phase)); defparam phacc_inst.WIDTH = PHACC_WIDTH; - sinelut sinelut_inst ( + sinelut sinelut_inst ( .address (phase), .clock (clk), .q(sine) ); - + + sdmod sdmod_inst ( + .val(sine), .clk(clk), .reset(clr_n), .daco(fout) + ); endmodule diff --git a/Testbench/sigdel/lut_mod_tb.sv b/Testbench/sigdel/lut_mod_tb.sv new file mode 100644 index 0000000..df55bd1 --- /dev/null +++ b/Testbench/sigdel/lut_mod_tb.sv @@ -0,0 +1,55 @@ +`timescale 1 ns/1 ns + +module lut_mod_tb(); + + // Parameters + localparam CLK_PRD = 20; + localparam PHACC_WIDTH = 14; + + logic clk, clr_n, wr_n, daco; + logic [7:0] phinc_val, phase, sine; + + // Instantiate UUT and connect used ports + phacc phacc ( + .phinc(phinc_val), .clk(clk), .reset(clr_n), .phase(phase) + ); + defparam phacc.WIDTH = PHACC_WIDTH; + + sinelut sinelut_inst ( + .address(phase), .clock(clk), .q(sine) + ); + + sdmod sdmod_inst ( + .val(sine), .clk(clk), .reset(clr_n), .daco(daco) +// .val(8'd0), .clk(clk), .reset(clr_n), .daco(daco) +// .val(8'd255), .clk(clk), .reset(clr_n), .daco(daco) + ); + + + // Clock definition + initial begin + clk = 0; + forever #(CLK_PRD/2) clk = ~clk; + end + + // Reset and initial values definition + initial begin + clr_n = 0; + #(CLK_PRD*5) clr_n = 1; + end + + // Bus write transaction simulation + initial begin + // Wait until system is out of reset + @(posedge clr_n); + + phinc_val=(2**(PHACC_WIDTH - 8)); + if ((phinc_val <= 255) && (phinc_val != 0)) begin + #(CLK_PRD * 256 * 10) $stop; + end else begin + $display("Error: value of phase increment is out of range! Stopped simulation."); + #1 $stop; + end + end +endmodule + diff --git a/Testbench/sigdel/sigdel.qsf b/Testbench/sigdel/sigdel.qsf index 81c3948..7a6d160 100644 --- a/Testbench/sigdel/sigdel.qsf +++ b/Testbench/sigdel/sigdel.qsf @@ -50,19 +50,28 @@ set_global_assignment -name NOMINAL_CORE_SUPPLY_VOLTAGE 1.2V set_global_assignment -name EDA_SIMULATION_TOOL "ModelSim-Altera (SystemVerilog)" set_global_assignment -name EDA_TIME_SCALE "1 ps" -section_id eda_simulation set_global_assignment -name EDA_OUTPUT_DATA_FORMAT "SYSTEMVERILOG HDL" -section_id eda_simulation -set_global_assignment -name SYSTEMVERILOG_FILE ../../HDL/phacc.sv set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" -set_global_assignment -name QIP_FILE ../../HDL/IP/sinelut.qip -set_global_assignment -name SYSTEMVERILOG_FILE ../../HDL/sigdel.sv -set_global_assignment -name SYSTEMVERILOG_FILE inc_lut_tb.sv set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top set_global_assignment -name EDA_TEST_BENCH_ENABLE_STATUS TEST_BENCH_MODE -section_id eda_simulation -set_global_assignment -name EDA_NATIVELINK_SIMULATION_TEST_BENCH inc_lut_tb -section_id eda_simulation +set_global_assignment -name EDA_NATIVELINK_SIMULATION_TEST_BENCH sigdel_tb -section_id eda_simulation set_global_assignment -name EDA_TEST_BENCH_NAME inc_lut_tb -section_id eda_simulation set_global_assignment -name EDA_DESIGN_INSTANCE_NAME NA -section_id inc_lut_tb set_global_assignment -name EDA_TEST_BENCH_MODULE_NAME inc_lut_tb -section_id inc_lut_tb +set_global_assignment -name EDA_TEST_BENCH_NAME lut_mod_tb -section_id eda_simulation +set_global_assignment -name EDA_DESIGN_INSTANCE_NAME NA -section_id lut_mod_tb +set_global_assignment -name EDA_TEST_BENCH_MODULE_NAME lut_mod_tb -section_id lut_mod_tb +set_global_assignment -name SYSTEMVERILOG_FILE ../../HDL/phacc.sv +set_global_assignment -name QIP_FILE ../../HDL/IP/sinelut.qip +set_global_assignment -name SYSTEMVERILOG_FILE ../../HDL/sigdel.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../../HDL/sdmod.sv +set_global_assignment -name EDA_NATIVELINK_SIMULATION_SETUP_SCRIPT simulation/modelsim/wave.do -section_id eda_simulation set_global_assignment -name EDA_TEST_BENCH_FILE inc_lut_tb.sv -section_id inc_lut_tb +set_global_assignment -name EDA_TEST_BENCH_FILE lut_mod_tb.sv -section_id lut_mod_tb +set_global_assignment -name EDA_TEST_BENCH_NAME sigdel_tb -section_id eda_simulation +set_global_assignment -name EDA_DESIGN_INSTANCE_NAME NA -section_id sigdel_tb +set_global_assignment -name EDA_TEST_BENCH_MODULE_NAME sigdel_tb -section_id sigdel_tb +set_global_assignment -name EDA_TEST_BENCH_FILE sigdel_tb.sv -section_id sigdel_tb set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/Testbench/sigdel/sigdel.sv b/Testbench/sigdel/sigdel.sv new file mode 100644 index 0000000..19d5764 --- /dev/null +++ b/Testbench/sigdel/sigdel.sv @@ -0,0 +1,37 @@ +//top-level module +module sigdel +#( + PHACC_WIDTH = 14 +) ( + //clock and reset + input logic clk, clr_n, + //control slave + input logic [31:0] wr_data, + input logic wr_n, + output logic fout +); + + logic [7:0] phinc_val; + + //control slave logic + always_ff @ (posedge clk or negedge clr_n) begin + if (!clr_n) begin + phinc_val[7:0] <= 8'd0; + end else begin + if (!wr_n) begin + phinc_val[7:0] <= wr_data[31:0]; + end + end + end + + phacc phacc_inst (.phinc(phinc_val), .clk(clk), .reset(clr_n), .phase(phase)); + defparam phacc_inst.WIDTH = PHACC_WIDTH; + + sinelut sinelut_inst ( + .address (phase), .clock (clk), .q(sine) + ); + + sdmod sdmod_inst ( + .val(sine), .clk(clk), .reset(clr_n), .daco(fout) + ); +endmodule diff --git a/Testbench/sigdel/sigdel_tb.sv b/Testbench/sigdel/sigdel_tb.sv new file mode 100644 index 0000000..ff7a645 --- /dev/null +++ b/Testbench/sigdel/sigdel_tb.sv @@ -0,0 +1,81 @@ +`timescale 1 ns/1 ns + +module sigdel_tb(); + + // Parameters + localparam CLK_PRD = 20; + localparam SAMPLES_PRD = 256; + localparam OVERSAMPLING = 4; + localparam PHACC_WIDTH = 14; + + // Wires and variables to connect to UUT (unit under test) + logic clk, clr_n, wr_n; + logic [31:0] wr_data; + logic [31:0] phinc_val; + logic fout; + + // Instantiate UUT and connect used ports + sigdel dut(.clk(clk), .clr_n(clr_n), .wr_n(wr_n), .wr_data(wr_data), .fout(fout)); + defparam dut.PHACC_WIDTH = PHACC_WIDTH; + + // Clock definition + initial begin + clk = 0; + forever #(CLK_PRD/2) clk = ~clk; + end + + // Reset and initial values definition + initial begin + clr_n = 0; + wr_n = 1; + wr_data = 'bx; + #(CLK_PRD*5) clr_n = 1; + end + + // Bus write transaction simulation + initial begin + // Wait until system is out of reset + @(posedge clr_n); + // Check if phase increment for required accumulator width + // and oversamlpling ratio will fit in 8 bits + phinc_val=(2**(PHACC_WIDTH-8))/OVERSAMPLING; + if ((phinc_val <= 255) && (phinc_val != 0)) + begin + // Write phase increment several clock cycles after reset + #(CLK_PRD*3) write_transaction(phinc_val); + // Wait for one sine period (for 14-bit phase accumulator case) + #(CLK_PRD*SAMPLES_PRD*OVERSAMPLING) + + #(CLK_PRD*3) write_transaction(phinc_val*5); + + #(CLK_PRD*SAMPLES_PRD*OVERSAMPLING) + $stop; + end + else + begin + //Output simulation error + $display("Error: value of phase increment is out of range! Stopped simulation."); + //Stop simulation (small delay needed for $display to work) + #1 $stop; + end + end + + //Single write transaction task + task write_transaction; + //input signals + input [31:0] val; + //transaction implementation + begin + @(posedge clk); + //assert signals for one clock cycle + wr_n = 0; + wr_data = val; + @(posedge clk); + //deassert signals + wr_n = 1; + wr_data = 'bx; + end + endtask + +endmodule +