lin-win-share/DA4008_V1.2/rtl/awg/awg_ctrl.v

159 lines
7.7 KiB
Verilog

//+FHDR--------------------------------------------------------------------------------------------------------
// Company:
//-----------------------------------------------------------------------------------------------------------------
// File Name : awg_ctrl.v
// Department :
// Author : hdzhang
// Author's Tel :
//-----------------------------------------------------------------------------------------------------------------
// Relese History
// Version Date Author Description
// 0.1 2026-02-28 hdzhang fifo-cmd controlled waveform output
//-----------------------------------------------------------------------------------------------------------------
// Keywords :
//
//-----------------------------------------------------------------------------------------------------------------
// Parameter
//
//-----------------------------------------------------------------------------------------------------------------
// Purpose :
//
//-----------------------------------------------------------------------------------------------------------------
// Target Device:
// Tool versions:
//-----------------------------------------------------------------------------------------------------------------
// Reuse Issues
// Reset Strategy:
// Clock Domains:
// Critical Timing:
// Asynchronous I/F:
// Synthesizable (y/n):
// Other:
//-FHDR--------------------------------------------------------------------------------------------------------
module awg_ctrl (
//system port
input clk // System Main Clock
,input rst_n // Spi Reset active low
//sync signal
,input start
//cmd fifo read signal
,output cmd_fifo_rd_en
,input [31 :0] cmd_fifo_data
,input cmd_fifo_empty
//wave sram read signals
,output sram_rd_en
,output [12 :0] sram_rd_addr
,input [511:0] sram_rd_data
//output to dem module
,output [511:0] wave_data_out
,output wave_valid_out
//state submit
,output [2 :0] status
,output wave_busy
);
localparam IDLE = 3'b0, CMD = 3'd1, WAVE = 3'd2, HOLD = 3'd3;
wire [2 : 0] state_c;
wire wave_cnt_add, wave_cnt_end;
wire [4 : 0] wave_cnt_c;
wire hold_cnt_add, hold_cnt_end;
wire [30 : 0] hold_cnt_c;
//wire cmd_fifo_has_empty = cmd_fifo_empty && cmd_fifo_rd_en;
// ------------------------------------------------------
// -- state machine
// ------------------------------------------------------
//jump conditions
wire ilde2cmd = (state_c == IDLE) && start;
wire cmd2wave = (state_c == CMD ) && ~cmd_fifo_data[31];
wire cmd2hold = (state_c == CMD ) && cmd_fifo_data[31];
wire wave2hold = (state_c == WAVE) && wave_cnt_end && cmd_fifo_data[31] && ~cmd_fifo_empty;
wire wave2idle = (state_c == WAVE) && wave_cnt_end && cmd_fifo_empty;
wire hold2wave = (state_c == HOLD) && hold_cnt_end && ~cmd_fifo_data[31] && ~cmd_fifo_empty;
wire hold2idle = (state_c == HOLD) && hold_cnt_end && cmd_fifo_empty;
//state_n
wire [2 : 0] state_n = ((state_c == IDLE) && ilde2cmd ) ? CMD :
((state_c == CMD ) && cmd2wave ) ? WAVE :
((state_c == CMD ) && cmd2hold ) ? HOLD :
((state_c == WAVE) && wave2hold ) ? HOLD :
((state_c == WAVE) && wave2idle ) ? IDLE :
((state_c == HOLD) && hold2wave ) ? WAVE :
((state_c == HOLD) && hold2idle ) ? IDLE :
state_c ;
//state_c
sirv_gnrl_dffr #(3) state_c_dffr (state_n, state_c, clk, rst_n);
// ------------------------------------------------------
// -- command decode
// ------------------------------------------------------
assign cmd_fifo_rd_en = ((state_c == CMD) || wave_cnt_end || hold_cnt_end) && ~cmd_fifo_empty;
wire [4 : 0] cycle_num;
wire [12 : 0] base_addr;
wire [12 : 0] wave_leng;
wire [30 : 0] hold_leng;
sirv_gnrl_dfflr #( 5) cycle_num_dfflr (cmd_fifo_rd_en && ~cmd_fifo_data[31], cmd_fifo_data[30:26], cycle_num, clk, rst_n);
sirv_gnrl_dfflr #(13) base_addr_dfflr (cmd_fifo_rd_en && ~cmd_fifo_data[31], cmd_fifo_data[25:13], base_addr, clk, rst_n);
sirv_gnrl_dfflr #(13) wave_leng_dfflr (cmd_fifo_rd_en && ~cmd_fifo_data[31], cmd_fifo_data[12: 0], wave_leng, clk, rst_n);
sirv_gnrl_dfflr #(31) hold_leng_dfflr (cmd_fifo_rd_en && cmd_fifo_data[31], cmd_fifo_data[30: 0], hold_leng, clk, rst_n);
// ------------------------------------------------------
// -- wave memory address count
// ------------------------------------------------------
wire [12 : 0] addr_cnt_c;
wire addr_cnt_add = (state_c == WAVE);
wire addr_cnt_end = addr_cnt_add && (addr_cnt_c == wave_leng - 1);
wire [12 : 0] addr_cnt_n = addr_cnt_end ? 13'h0 :
addr_cnt_add ? addr_cnt_c + 1'b1 :
addr_cnt_c ;
sirv_gnrl_dffr #(13) addr_cnt_c_dffr (addr_cnt_n, addr_cnt_c, clk, rst_n);
// ------------------------------------------------------
// -- wave repeat count
// ------------------------------------------------------
assign wave_cnt_add = addr_cnt_end;
assign wave_cnt_end = wave_cnt_add && (wave_cnt_c == cycle_num - 1) && (cycle_num != 5'd0);
wire [4 : 0] wave_cnt_n = wave_cnt_end ? 5'h0 :
wave_cnt_add ? wave_cnt_c + 1'b1 :
wave_cnt_c ;
sirv_gnrl_dffr #( 5) wave_cnt_c_dffr (wave_cnt_n, wave_cnt_c, clk, rst_n);
// ------------------------------------------------------
// -- hold length count
// ------------------------------------------------------
assign hold_cnt_add = (state_c == HOLD);
assign hold_cnt_end = hold_cnt_add && (hold_cnt_c == hold_leng - 1);
wire [30 : 0] hold_cnt_n = hold_cnt_end ? 5'h0 :
hold_cnt_add ? hold_cnt_c + 1'b1 :
hold_cnt_c ;
sirv_gnrl_dffr #(31) hold_cnt_c_dffr (hold_cnt_n, hold_cnt_c, clk, rst_n);
// ------------------------------------------------------
// -- read wave SRAM
// ------------------------------------------------------
sirv_gnrl_dffr #(1) sram_rd_en_dffr ((state_c == WAVE), sram_rd_en, clk, rst_n);
sirv_gnrl_dffr #(13) sram_rd_addr_dffr (base_addr + addr_cnt_c, sram_rd_addr, clk, rst_n);
wire last_sram_rd_en, last_wave_data_vld;
wire [7 : 0] last_rddata;
sirv_gnrl_dffr #(1) last_sram_rd_en_dffr (wave_cnt_end, last_sram_rd_en, clk, rst_n);
sirv_gnrl_dffr #(1) last_wave_data_dffr (last_sram_rd_en, last_wave_data_vld, clk, rst_n);
sirv_gnrl_dfflr #(8) last_rddata_dfflr (last_wave_data_vld, sram_rd_data[511:504], last_rddata, clk, rst_n);
wire wave_vld, hold_vld_n, hold_vld;
sirv_gnrl_dffr #(1) wave_vld_dffr (sram_rd_en, wave_vld, clk, rst_n);
sirv_gnrl_dffr #(1) hold_vld_n_dffr ((state_c == HOLD), hold_vld_n, clk, rst_n);
sirv_gnrl_dffr #(1) hold_vld_dffr (hold_vld_n, hold_vld, clk, rst_n);
wire [511: 0] wave_data = wave_vld ? sram_rd_data :
hold_vld ? {64{last_rddata}} :
512'd0 ;
sirv_gnrl_dffr #(1) wave_valid_dffr (wave_vld | hold_vld, wave_valid_out, clk, rst_n);
sirv_gnrl_dfflr #(512) wave_data_dfflr (wave_vld | hold_vld | wave_valid_out, wave_data, wave_data_out, clk, rst_n);
//status
assign status = state_c;
assign wave_busy = (state_c == WAVE) || (state_c == HOLD);
endmodule