| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- `timescale 1 ns / 1 ps
- module axis_i2s #
- (
- parameter integer AXIS_TDATA_WIDTH = 32
- )
- (
- // System signals
- input wire aclk,
- input wire aresetn,
- // I2S signals
- inout wire [3:0] gpio_data,
- // ALEX signals
- input wire alex_flag,
- input wire [3:0] alex_data,
- // Slave side
- output wire s_axis_tready,
- input wire [AXIS_TDATA_WIDTH-1:0] s_axis_tdata,
- input wire s_axis_tvalid,
- // Master side
- input wire m_axis_tready,
- output wire [AXIS_TDATA_WIDTH-1:0] m_axis_tdata,
- output wire m_axis_tvalid
- );
- localparam I2S_DATA_WIDTH = AXIS_TDATA_WIDTH / 2;
- localparam CNTR_WIDTH = 6;
- reg [2:0] int_bclk_reg, int_lrclk_reg;
- reg [1:0] int_data_reg;
- reg [1:0] adc_case_reg, adc_case_next;
- reg [CNTR_WIDTH-1:0] adc_cntr_reg, adc_cntr_next;
- reg [I2S_DATA_WIDTH-1:0] adc_data_reg, adc_data_next;
- reg [AXIS_TDATA_WIDTH-1:0] adc_tdata_reg, adc_tdata_next;
- reg adc_tvalid_reg, adc_tvalid_next;
- reg [1:0] dac_case_reg, dac_case_next;
- reg [I2S_DATA_WIDTH-1:0] dac_data_reg, dac_data_next;
- reg [AXIS_TDATA_WIDTH-1:0] dac_tdata_reg, dac_tdata_next;
- wire i2s_bclk, i2s_lrclk, i2s_adc_data, i2s_dac_data;
- wire int_bclk_posedge, int_bclk_negedge, int_lrclk_negedge;
- wire not_alex_flag = ~alex_flag;
- IOBUF buf_bclk (.O(i2s_bclk), .IO(gpio_data[0]), .I(alex_data[0]), .T(not_alex_flag));
- IOBUF buf_adc_data (.O(i2s_adc_data), .IO(gpio_data[1]), .I(alex_data[1]), .T(not_alex_flag));
- IOBUF buf_dac_data (.O(), .IO(gpio_data[2]), .I(alex_flag ? alex_data[2] : i2s_dac_data), .T(1'b0));
- IOBUF buf_lrclk (.O(i2s_lrclk), .IO(gpio_data[3]), .I(alex_data[3]), .T(not_alex_flag));
- always @(posedge aclk)
- begin
- if(~aresetn)
- begin
- int_bclk_reg <= 3'd0;
- int_lrclk_reg <= 3'd0;
- int_data_reg <= 2'd0;
- adc_case_reg <= 2'd0;
- adc_cntr_reg <= {(CNTR_WIDTH){1'b0}};
- adc_data_reg <= {(I2S_DATA_WIDTH){1'b0}};
- adc_tdata_reg <= {(AXIS_TDATA_WIDTH){1'b0}};
- adc_tvalid_reg <= 1'b0;
- dac_case_reg <= 2'd0;
- dac_data_reg <= {(I2S_DATA_WIDTH){1'b0}};
- dac_tdata_reg <= {(AXIS_TDATA_WIDTH){1'b0}};
- end
- else
- begin
- int_bclk_reg <= {int_bclk_reg[1:0], i2s_bclk};
- int_lrclk_reg <= {int_lrclk_reg[1:0], i2s_lrclk};
- int_data_reg <= {int_data_reg[0], i2s_adc_data};
- adc_case_reg <= adc_case_next;
- adc_cntr_reg <= adc_cntr_next;
- adc_data_reg <= adc_data_next;
- adc_tdata_reg <= adc_tdata_next;
- adc_tvalid_reg <= adc_tvalid_next;
- dac_case_reg <= dac_case_next;
- dac_data_reg <= dac_data_next;
- dac_tdata_reg <= dac_tdata_next;
- end
- end
- assign int_bclk_posedge = int_bclk_reg[1] & ~int_bclk_reg[2];
- assign int_bclk_negedge = ~int_bclk_reg[1] & int_bclk_reg[2];
- assign int_lrclk_negedge = ~int_lrclk_reg[1] & int_lrclk_reg[2];
- always @*
- begin
- adc_case_next = adc_case_reg;
- adc_cntr_next = adc_cntr_reg;
- adc_data_next = adc_data_reg;
- adc_tdata_next = adc_tdata_reg;
- adc_tvalid_next = adc_tvalid_reg;
- if(int_bclk_posedge & (adc_cntr_reg < I2S_DATA_WIDTH))
- begin
- adc_data_next = {adc_data_reg[I2S_DATA_WIDTH-2:0], int_data_reg[1]};
- adc_cntr_next = adc_cntr_reg + 1'b1;
- end
- if(m_axis_tready & adc_tvalid_reg)
- begin
- adc_tvalid_next = 1'b0;
- end
- case(adc_case_reg)
- 2'd0:
- begin
- if(int_lrclk_reg[1] ^ int_lrclk_reg[2])
- begin
- adc_case_next = 2'd1;
- end
- end
- 2'd1:
- begin
- if(int_bclk_posedge)
- begin
- adc_cntr_next = {(CNTR_WIDTH){1'b0}};
- adc_case_next = 2'd2;
- end
- end
- 2'd2:
- begin
- if(int_bclk_posedge)
- begin
- adc_tvalid_next = ~int_lrclk_reg[1];
- adc_tdata_next = {adc_tdata_reg[I2S_DATA_WIDTH-1:0], adc_data_reg};
- adc_case_next = 2'd0;
- end
- end
- endcase
- end
- always @*
- begin
- dac_case_next = dac_case_reg;
- dac_data_next = dac_data_reg;
- dac_tdata_next = dac_tdata_reg;
- if(int_bclk_negedge)
- begin
- dac_data_next = {dac_data_reg[I2S_DATA_WIDTH-2:0], 1'b0};
- end
- if(int_lrclk_negedge)
- begin
- dac_tdata_next = s_axis_tvalid ? s_axis_tdata : {(AXIS_TDATA_WIDTH){1'b0}};
- end
- case(dac_case_reg)
- 2'd0:
- begin
- if(int_lrclk_reg[1] ^ int_lrclk_reg[2])
- begin
- dac_case_next = 2'd1;
- end
- end
- 2'd1:
- begin
- if(int_bclk_posedge)
- begin
- dac_case_next = 2'd2;
- end
- end
- 2'd2:
- begin
- if(int_bclk_negedge)
- begin
- dac_data_next = int_lrclk_reg[1] ? dac_tdata_reg[I2S_DATA_WIDTH-1:0] : dac_tdata_reg[AXIS_TDATA_WIDTH-1:I2S_DATA_WIDTH];
- dac_case_next = 2'd0;
- end
- end
- endcase
- end
- assign i2s_dac_data = dac_data_reg[I2S_DATA_WIDTH-1];
- assign s_axis_tready = int_lrclk_negedge;
- assign m_axis_tdata = adc_tdata_reg;
- assign m_axis_tvalid = adc_tvalid_reg;
- endmodule
|