updates to ofdm waveform gen

This commit is contained in:
2025-10-17 11:52:35 -05:00
parent 086c5dd9f3
commit 60ac0021c8
10 changed files with 951 additions and 51 deletions

View File

@@ -0,0 +1,28 @@
`resetall
`timescale 1ns / 1ps
`default_nettype none
module delay_shift_register #(
parameter DELAY_CYCLES = 4
) (
input wire clk,
input wire reset,
input wire data_in,
output wire data_out
);
// Declare a register to hold the shifted data
reg [DELAY_CYCLES-1:0] shift_reg;
always @ (posedge clk) begin
if (reset) begin
shift_reg <= '0;
end else begin
shift_reg <= {shift_reg[DELAY_CYCLES-2:0], data_in};
end
end
assign data_out = shift_reg[DELAY_CYCLES-1];
endmodule
`resetall

View File

@@ -2,6 +2,75 @@
`timescale 1ns / 1ps
`default_nettype none
// Outputs 4 IQ samples in parallel for connection to DAC interface
// start_pulse - Kicks off output for a single pulse, expected to be a single clock wide
// start_table_irq - This is used to indicate to software that playback from the top of the sequence table has begin
// half_table_irq - This is used to indicate to software that playback from the mid point of the sequence table has begin
// The mid point is defined as (n_total_chips >> 1)
// These interrupts are used in combination to enable software to continually update the sequence table in a ping pong
// fashion while the system is operating
/*
* ADDR=0x0000 Control Register (reg_ctrl)
* Currently unused
*/
/*
* ADDR=0x0004 Start Frequency Register (reg_start_freq)
* Sets the value of the lowest frequency chip, final chip frequincies are calculated using this value,
* the delta frequency, and the sequence number from the ram
* Bit 31:0: Frequency
*/
/*
* ADDR=0x0008 Chip Description 0 (reg_chips_0)
* Bit 15:0: Number of total chips in the sequence table
*/
/*
* ADDR=0x000C Chip Description 1 (reg_chips_1)
* Bit 15:0: Number of DAC samples per chip divided by 4 (due to parallel output of 4 samples)
* Bit 31:16: Number of Chips per Pulse
*/
/*
* ADDR=0x0010 Delta Frequency Register (reg_start_freq)
* Sets the delta frequency value between chips, final chip frequincies are calculated using this value,
* the delta frequency, and the sequence number from the ram
* Bit 31:0: Delta Frequency
*/
/*
* ADDR=0x0014 Currently Unused
*/
/*
* ADDR=0x0018 Sequence Memory Write Address
* Sets the write address of the sequence memory
* Bit 15:0: BRAM Write Address
*/
/*
* ADDR=0x001C Sequence Memory Write Data
* Write a value into the sequence BRAM, and automatically increments the address.
* Repeated writes to this registers store values in sequential address in the BRAM
* Bit 15:0: BRAM Write Data
*/
/*
* ADDR=0x0020 Start Phase Memory Write Address
* Sets the write address of the sequence memory
* Bit 15:0: BRAM Write Address
*/
/*
* ADDR=0x0024 Start Phase Memory Write Data
* Write a value into the sequence BRAM, and automatically increments the address.
* Repeated writes to this registers store values in sequential address in the BRAM
* Bit 15:0: BRAM Write Data
*/
module gen_ofdm # (
parameter integer AXI_ADDR_WIDTH = 32,
parameter integer AXI_DATA_WIDTH = 32
@@ -13,10 +82,50 @@ module gen_ofdm # (
input wire start_pulse,
output wire start_table_irq,
output wire half_table_irq,
output wire [127:0] iq_out,
output wire iq_out_valid
);
// ------------------------------
// BRAM for holding sequence
// ------------------------------
wire [15:0] read_addr;
wire [15:0] read_sequence;
reg bram_we;
reg [15:0] bram_waddr;
reg [15:0] bram_wdata;
ofdm_sequence_ram sequence_ram (
.clka(ctrl_if.clk),
.ena(1'b1),
.wea(bram_we),
.addra(bram_waddr),
.dina(bram_wdata),
.clkb(clk),
.enb(1'b1),
.addrb(read_addr),
.doutb(read_sequence)
);
wire [15:0] read_phase;
reg phase_bram_we;
reg [15:0] phase_bram_waddr;
reg [15:0] phase_bram_wdata;
ofdm_sequence_ram phase_ram (
.clka(ctrl_if.clk),
.ena(1'b1),
.wea(phase_bram_we),
.addra(phase_bram_waddr),
.dina(phase_bram_wdata),
.clkb(clk),
.enb(1'b1),
.addrb(read_addr),
.doutb(read_phase)
);
// ------------------------------
// AXIL Decode
// ------------------------------
@@ -69,39 +178,79 @@ axil_slave
// Config Registers
// ------------------------------
reg [31:0] reg_ctrl;
reg [31:0] reg_freq;
reg [31:0] reg_phase;
reg [31:0] reg_chips;
reg [31:0] reg_start_freq;
reg [31:0] reg_delta_freq;
reg [31:0] reg_delta_phase;
reg [31:0] reg_chips_0;
reg [31:0] reg_chips_1;
always @ (posedge ctrl_if.clk) begin
if (~ctrl_if.resetn) begin
reg_ctrl <= 0;
reg_freq <= 0;
reg_phase <= 0;
reg_start_freq <= 0;
reg_delta_freq <= 0;
reg_chips_0 <= 0;
reg_chips_1 <= 0;
reg_delta_phase <= 0;
bram_we <= 1'b0;
bram_waddr <= 0;
bram_wdata <= 0;
phase_bram_we <= 1'b0;
phase_bram_waddr <= 0;
phase_bram_wdata <= 0;
end else begin
bram_we <= 1'b0;
if (bram_we) begin
bram_waddr <= bram_waddr + 1;
end
phase_bram_we <= 1'b0;
if (phase_bram_we) begin
phase_bram_waddr <= phase_bram_waddr + 1;
end
if (wren) begin
if (waddr[11:0] == 'h000) begin
reg_ctrl <= wdata;
end
if (waddr[11:0] == 'h004) begin
reg_freq <= wdata;
reg_start_freq <= wdata;
end
if (waddr[11:0] == 'h008) begin
reg_phase <= wdata;
reg_chips_0 <= wdata;
end
if (waddr[11:0] == 'h00C) begin
reg_chips <= wdata;
reg_chips_1 <= wdata;
end
// if (waddr[11:0] == 'h010) begin
// reg_phase <= wdata;
// end
if (waddr[11:0] == 'h010) begin
reg_delta_freq <= wdata;
end
if (waddr[11:0] == 'h014) begin
reg_delta_phase <= wdata;
end
if (waddr[11:0] == 'h018) begin
bram_waddr <= wdata;
end
if (waddr[11:0] == 'h01C) begin
bram_we <= 1'b1;
bram_wdata <= wdata;
end
if (waddr[11:0] == 'h020) begin
phase_bram_waddr <= wdata;
end
if (waddr[11:0] == 'h024) begin
phase_bram_we <= 1'b1;
phase_bram_wdata <= wdata;
end
end
end
end
wire [15:0] n_samp_chip = reg_chips[15:0];
wire [15:0] n_chip = reg_chips[31:16];
wire [15:0] n_total_chips = reg_chips_0[15:0];
wire [15:0] n_samp_per_chip = reg_chips_1[15:0];
wire [15:0] n_chip_per_pulse = reg_chips_1[31:16];
// ------------------------------
// Bla
@@ -109,47 +258,116 @@ wire [15:0] n_chip = reg_chips[31:16];
reg [24:0] pulse_cnt;
reg [15:0] chip_cnt;
reg [15:0] chip_ind;
reg [15:0] chip_per_pulse_cnt;
reg pulse_active;
reg start_of_pulse;
wire set_phase;
reg start_irq;
reg half_irq;
assign read_addr = chip_ind;
assign start_table_irq = start_irq;
assign half_table_irq = half_irq;
always @ (posedge clk) begin
if (reset) begin
chip_cnt <= 0;
chip_ind <= 0;
chip_per_pulse_cnt <= 0;
pulse_active <= 1'b0;
start_of_pulse <= 1'b0;
end else begin
start_of_pulse <= 1'b0;
if (start_pulse) begin
chip_cnt <= 0;
chip_ind <= 0;
chip_per_pulse_cnt <= 0;
pulse_active <= 1'b1;
start_of_pulse <= 1'b1;
end
if (pulse_active) begin
chip_cnt <= chip_cnt + 1;
if (chip_cnt == n_samp_chip - 1) begin
if (chip_cnt == n_samp_per_chip - 1) begin
chip_cnt <= 0;
chip_ind <= chip_ind + 1;
if (chip_ind == n_chip - 1) begin
chip_ind <= 0;
pulse_active = 1'b0;
chip_per_pulse_cnt <= chip_per_pulse_cnt + 1;
if (chip_per_pulse_cnt == n_chip_per_pulse - 1) begin
chip_per_pulse_cnt <= 0;
pulse_active <= 1'b0;
if (chip_ind == n_total_chips-1) begin
chip_ind <= 0;
end
end
end
end
start_irq <= 1'b0;
if (pulse_active) begin
if (chip_cnt == 0) begin
if (chip_ind == 0) begin
start_irq <= 1'b1;
end
end
end
half_irq <= 1'b0;
if (pulse_active) begin
if (chip_cnt == 0) begin
if (chip_ind == (n_total_chips >> 1)) begin
half_irq <= 1'b1;
end
end
end
end
end
wire [47:0] mult_out;
wire [31:0] chip_delta_freq;
ofdm_freq_mult freq_mult (
.CLK(clk),
.A(reg_delta_freq),
.B(read_sequence),
.P(mult_out)
);
assign chip_delta_freq = mult_out[31:0];
reg [31:0] chip_freq;
reg [15:0] read_phase_q;
reg [15:0] read_phase_q2;
always @ (posedge clk) begin
chip_freq <= chip_delta_freq + reg_start_freq;
read_phase_q <= read_phase;
read_phase_q2 <= read_phase_q;
end
assign set_phase = (chip_cnt == 0) ? pulse_active : 1'b0;
wire pulse_active_delayed;
delay_shift_register # (
.DELAY_CYCLES(4)
) delay_valid (
.clk(clk),
.reset(reset),
.data_in(pulse_active),
.data_out(pulse_active_delayed)
);
wire set_phase_delayed;
delay_shift_register # (
.DELAY_CYCLES(4)
) delay_set_phase (
.clk(clk),
.reset(reset),
.data_in(set_phase),
.data_out(set_phase_delayed)
);
gen_sine gen_sine_i (
.clk(clk),
.reset(reset),
.set_phase(start_of_pulse),
.valid(pulse_active),
.phase(reg_phase),
.frequency(reg_freq),
.set_phase(set_phase_delayed),
.valid(pulse_active_delayed),
.phase({read_phase_q2, 16'h0000}),
.frequency(chip_freq),
.iq_out(iq_out),
.iq_out_valid(iq_out_valid)
);