diff --git a/Basys3_Master.xdc b/Basys3_Master.xdc index 17d69bb..d4d8f04 100644 --- a/Basys3_Master.xdc +++ b/Basys3_Master.xdc @@ -3,11 +3,16 @@ ## - uncomment the lines corresponding to used pins ## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project +## CFGBVS +set_property CFGBVS VCCO [current_design] + set_property CONFIG_VOLTAGE 3.3 [current_design] + ## Clock signal set_property PACKAGE_PIN W5 [get_ports clk] set_property IOSTANDARD LVCMOS33 [get_ports clk] create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports clk] - + + ## Switches #set_property PACKAGE_PIN V17 [get_ports {sw[0]}] #set_property IOSTANDARD LVCMOS33 [get_ports {sw[0]}] diff --git a/debounce_switch.v b/debounce_switch.v index c3c32aa..d484fcc 100644 --- a/debounce_switch.v +++ b/debounce_switch.v @@ -4,7 +4,8 @@ module debounce_switch( output o_switch); // parameter c_debounce_limit=250000;// 2.5ms at 25MHz - parameter c_debounce_limit=1_000_000;// 10ms at 25MHz +// parameter c_debounce_limit=1_000_000;// 10ms at 100MHz + parameter c_debounce_limit=100_000; // 10ms at 10MHz reg r_state=1'b0; reg [19:0] r_count = 0; diff --git a/effect_controler.v b/effect_controler.v index 1da27c5..2b75a42 100644 --- a/effect_controler.v +++ b/effect_controler.v @@ -2,10 +2,10 @@ module effect_controler #( parameter d_width = 24 // data width )( // input clk, - input [d_width-1: 0] i_l_data, - input [d_width-1: 0] i_r_data, - output [d_width-1: 0] o_l_data, - output [d_width-1: 0] o_r_data + input signed [d_width-1: 0] i_l_data, + input signed [d_width-1: 0] i_r_data, + output signed [d_width-1: 0] o_l_data, + output signed [d_width-1: 0] o_r_data ); assign o_l_data = i_l_data; diff --git a/i2s_transceiver.v b/i2s_transceiver.v index c0e2cc9..db49dfb 100644 --- a/i2s_transceiver.v +++ b/i2s_transceiver.v @@ -33,23 +33,23 @@ module i2s_transceiver #( parameter output ws, //word select (or left-right clock) output sd_tx, //serial data transmit input sd_rx, //serial data receive - input [d_width-1: 0] l_data_tx, //left channel data to transmit - input [d_width-1: 0] r_data_tx, //right channel data to transmit - output [d_width-1: 0] l_data_rx, //left channel data received - output [d_width-1: 0] r_data_rx //right channel data received + input signed [d_width-1: 0] l_data_tx, //left channel data to transmit + input signed [d_width-1: 0] r_data_tx, //right channel data to transmit + output signed [d_width-1: 0] l_data_rx, //left channel data received + output signed [d_width-1: 0] r_data_rx //right channel data received ); reg sclk_int = 0; //internal serial clock wire reg ws_int = 0; //internal word select wire -reg [d_width-1: 0] l_data_rx_int = 0; //internal left channel rx data buffer -reg [d_width-1: 0] r_data_rx_int = 0; //internal right channel rx data buffer -reg [d_width-1: 0] l_data_tx_int = 0; //internal left channel tx data buffer -reg [d_width-1: 0] r_data_tx_int = 0; //internal right channel tx data buffer +reg signed [d_width-1: 0] l_data_rx_int = 0; //internal left channel rx data buffer +reg signed [d_width-1: 0] r_data_rx_int = 0; //internal right channel rx data buffer +reg signed [d_width-1: 0] l_data_tx_int = 0; //internal left channel tx data buffer +reg signed [d_width-1: 0] r_data_tx_int = 0; //internal right channel tx data buffer reg r_sd_tx = 0; //internal register -reg [d_width-1: 0] reg_r_data_rx = 0; -reg [d_width-1: 0] reg_l_data_rx = 0; +reg signed [d_width-1: 0] reg_r_data_rx = 0; +reg signed [d_width-1: 0] reg_l_data_rx = 0; reg [2: 0] sclk_cnt = 0; //counter of master clocks during half period of serial clock @@ -57,9 +57,9 @@ reg [7: 0] ws_cnt = 0; //counter of serial clock toggles during half period o -always@(mclk , reset_n) begin +always@(posedge mclk, posedge reset_n) begin - if (reset_n == 0) begin + if (reset_n == 1) begin sclk_cnt <= 'b0; //clear mclk/sclk counter ws_cnt <= 'b0; //clear sclk/ws counter sclk_int <= 0; //clear serial clock signal @@ -72,7 +72,7 @@ always@(mclk , reset_n) begin reg_l_data_rx <= 'b0; //clear left channel received data output reg_r_data_rx <= 'b0; //clear right channel received data output end - else if (mclk == 1) begin //master clock rising edge + else begin //master clock rising edge if (sclk_cnt < mclk_sclk_ratio/2-1) begin //less than half period of sclk sclk_cnt <= sclk_cnt + 1; //increment mclk/sclk counter end @@ -101,8 +101,8 @@ always@(mclk , reset_n) begin end else begin //half period of ws ws_cnt <= 0; //reset sclk/ws counter ws_int <= ~ws_int; //toggle word select - reg_r_data_rx <= r_data_rx_int; //output right channel received data - reg_l_data_rx <= l_data_rx_int; //output left channel received data +// reg_r_data_rx <= r_data_rx_int; //output right channel received data +// reg_l_data_rx <= l_data_rx_int; //output left channel received data r_data_tx_int <= r_data_tx; //latch in right channel data to transmit l_data_tx_int <= l_data_tx; //latch in left channel data to transmit end @@ -113,7 +113,9 @@ end assign sclk = sclk_int; //output serial clock assign ws = ws_int; //output word select assign sd_tx = r_sd_tx; //assign sd_tx -assign r_data_rx = reg_r_data_rx; -assign l_data_rx = reg_l_data_rx; +//assign r_data_rx = reg_r_data_rx; +//assign l_data_rx = reg_l_data_rx; +assign r_data_rx = ~(ws_cnt < sclk_ws_ratio - 1)? r_data_rx_int: r_data_rx ; +assign l_data_rx = ~(ws_cnt < sclk_ws_ratio - 1)? l_data_rx_int: l_data_rx ; endmodule \ No newline at end of file diff --git a/i2s_transceiver_tb.v b/i2s_transceiver_tb.v index 6a3f3d0..a657d5b 100644 --- a/i2s_transceiver_tb.v +++ b/i2s_transceiver_tb.v @@ -12,7 +12,7 @@ `include "i2s_transceiver.v" module i2s_transceiver_tb#( parameter - sclk_ws_ratio = 64, // number of sclk periods per word select period + sclk_ws_ratio = 48, // number of sclk periods per word select period mclk_sclk_ratio = 4, // number of mclk periods per sclk period d_width = 24 // data width )(); @@ -32,7 +32,13 @@ wire [d_width-1: 0] r_data_rx; // 50% duty cycle clock always #0.5 clk <= ~clk; -i2s_transceiver UUT( +always #4 sd_rx <= ~sd_rx; + +i2s_transceiver #( + .mclk_sclk_ratio(mclk_sclk_ratio), //number of mclk periods per sclk period + .sclk_ws_ratio(sclk_ws_ratio), //number of sclk periods per word select period + .d_width(d_width) //data width +) UUT( .reset_n(reset_n), //asynchronous active low reset .mclk(clk), //master clock .sclk(sclk), //serial clock (or bit clock) @@ -47,13 +53,13 @@ i2s_transceiver UUT( initial begin - #200 - reset_n <= 1; - #200 - l_data_tx = 'h2563; - r_data_tx = 'h1523; - #20 - sd_rx = 'h1; + #0 + reset_n <= 0; +// #200 + l_data_tx = 'hbbbbbb; + r_data_tx = 'haaaaaa; +// #20 +// sd_rx = 'h1; end diff --git a/top.v b/top.v index dd84d80..a41fecf 100644 --- a/top.v +++ b/top.v @@ -1,15 +1,6 @@ // TOP module // -// Fs = audio sample frequency -// I2S bitrate = (#bits/channel) x (#channels) x Fs -// Ex: 24-bit stereo (2 channels) -// I2S bitrate = 24 x 2 x Fs -// -// I2SxCLK source = PLLI2S output or ext. input (I2S_CKIN) -// Fs = 48kHz, 96kHz or 192kHz -// Fs = I2SxCLK / [(CF*2) * (2*I2SDIV+ODD)*8)] -// CF = channel frame (24 bits) -// + module top #( parameter @@ -55,7 +46,7 @@ i2s_transceiver #( .sclk_ws_ratio(sclk_ws_ratio), //number of sclk periods per word select period .d_width(d_width) //data width ) i2s_transceiver ( - .reset_n(~reset_n), //asynchronous active low reset + .reset_n(reset_n), //asynchronous active high reset .mclk(master_clk), //master clock .sclk(serial_clk), //serial clock (or bit clock) .ws(word_select), //word select (or left-right clock) @@ -80,7 +71,7 @@ effect_controler #( //debounce reset button debounce_switch debounce_switch_reset( - .clk(clk), + .clk(master_clk), .i_switch(btnC), .o_switch(reset_n) );