Created
July 20, 2023 14:20
-
-
Save ruilvo/adbbf3f729a55dd149963ab1e4ed2556 to your computer and use it in GitHub Desktop.
Verilog SONAR
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| module peak_detect( | |
| //----------------------------------------------- | |
| // Global signals | |
| input DIN_RDY, // data in is ready AKA 48kHz clock | |
| input starttx, //so we know when we start counting | |
| input endtx, | |
| input clock, // master clock, active in posedge | |
| input reset, // master reset, synchronous, active high | |
| input corr_rdy, // New correlation available | |
| input [41:0] corrin, // new correlation input | |
| output reg [15:0] pktimeoutput //time between start_tx and pk | |
| ); | |
| //Counter that counts samples that arrived since the tranmission started | |
| reg [15:0] contador; | |
| always @ (posedge clock) begin | |
| if (reset) contador <= 0; | |
| else begin | |
| if (starttx || endtx) contador <= 0; | |
| else begin | |
| if (DIN_RDY) contador <= contador + 1; | |
| else contador <= contador; | |
| end | |
| end | |
| end | |
| reg [15:0] pktimetmp; | |
| reg [41:0] maxcorrun; // read "max corr until now" | |
| //Peak detector | |
| always @ (posedge clock) begin | |
| if (reset) begin | |
| pktimetmp <= 0; | |
| maxcorrun <= 0; | |
| end | |
| else begin | |
| if (starttx) begin //On starttx reset the values | |
| pktimetmp <= 0; | |
| maxcorrun <= 0; | |
| end | |
| else begin | |
| if (corrin > maxcorrun) begin | |
| pktimetmp <= contador; | |
| maxcorrun <= corrin; | |
| end | |
| else begin | |
| pktimetmp <= pktimetmp; | |
| maxcorrun <= maxcorrun; | |
| end | |
| end | |
| end | |
| end | |
| //Peak detector output | |
| always @ (posedge clock) begin | |
| if (reset) pktimeoutput <= 0; | |
| else begin | |
| if (starttx) pktimeoutput <= pktimetmp; | |
| else pktimeoutput <= pktimeoutput; | |
| end | |
| end | |
| endmodule |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| module sonar_rx( | |
| //----------------------------------------------- | |
| // Global signals | |
| input clock, // master clock, active in posedge | |
| input reset, // master reset, synchronous, active high | |
| input [9:0] Nsamples, // Number of samples of the reference signal | |
| //----------------------------------------------- | |
| // Audio data in: | |
| input signed [15:0] audioin, // audio data in | |
| input DIN_RDY, // data in is ready | |
| //----------------------------------------------- | |
| // Raw correlation output (unsigned, absolute value) | |
| output reg signed [41:0] corrout, // data out, correlation output | |
| output reg corr_rdy, //we have a new correlation available | |
| input signed [31:0] ref_sig, | |
| input signed [31:0] ref_sigm1, | |
| output reg [8:0] refaddr, | |
| output reg [8:0] refaddrm1 | |
| ); | |
| //----------------------------------------------------------------- | |
| // Instantiate the circular buffer, 1K samples, 4 data samples per read: | |
| wire [7:0] readaddr; | |
| wire signed [71:0] audio4out; // 4 audio samples, 18 bits per sample | |
| RAM_CB_1k RAM_CB_1k_1 | |
| ( | |
| .clock( clock ), | |
| .reset( reset ), | |
| // Write port, internal addressing: | |
| .din( {2'b00, audioin} ), // input audio stream: zero the two MSbits | |
| .wen( DIN_RDY ), // input data enable (this is the write enable to the memory) | |
| // Read port, 256 data, 4 audio samples per read | |
| .addrin( readaddr ), // read address: each memory read outputs 4 data samples | |
| .dout( audio4out ) // 4 data samples, 16 bit signed | |
| ); | |
| // 4 data samples read from the circular buffer: | |
| wire signed [15:0] audio0, audio1, audio2, audio3; | |
| // Split data read into separate samples | |
| // Remove the two MSbits, we'll use only the lower 16 LSBits | |
| assign audio0 = audio4out[71-2:54]; // this is the most recent sample | |
| assign audio1 = audio4out[53-2:36]; | |
| assign audio2 = audio4out[35-2:18]; | |
| assign audio3 = audio4out[17-2: 0]; // this is the oldest sample | |
| // accumulator for the correlation function: | |
| reg signed [41:0] correlation = 42'd0; | |
| // This is the memory holding the reference signal, two samples per memory location. | |
| // With some adjustments, this memory could be the same as the RAM memory | |
| // used for the TX channel (see register array 'datamemory' in module sonar_tx.v). | |
| // | |
| // However, to share this memory between the two processes we must be able to read | |
| // the memory for the receive process while the transmission is running. | |
| // | |
| // The tx data memory is presently organized as a 32bit x 512, holding two 16-bit samples | |
| // in each memory location. This memory may be written by the serial interface, two samples | |
| // per write operation and pre-loaded at compile time with a data file created by the | |
| // Matlab script "create_simdata.m". | |
| /* | |
| //################################################ TO BE FIXED ################################ | |
| // This parameter must be defined in the testbench | |
| parameter REF_IN_FILENAME = "*** FILENAME NOT VALID ***"; | |
| // In this simulation model, we use a second memory with the same organization of the memory | |
| // present in the tx module. This memory is not loadable via the serial interface and can only | |
| // be pre-loaded with the data from the file REF_IN_FILENAME | |
| reg signed [31:0] refsignal[0:511]; | |
| // Load the memory with the reference signal: | |
| integer i; | |
| initial begin | |
| $display("Loading reference signal from file %s:", REF_IN_FILENAME ); | |
| for(i=0; i<512; i=i+1) | |
| refsignal[i] = 0; | |
| $readmemh( REF_IN_FILENAME, refsignal ); | |
| end | |
| assign ref23 = refsignal[refaddrm1]; | |
| assign ref01 = refsignal[refaddr]; | |
| // Registers to read two 32-bit words (two samples each) | |
| wire [31:0] ref01, ref23; | |
| // The four data samples read from the reference signal | |
| // These must be signed for the implementation of the multiplication: | |
| wire signed [15:0] ref0, ref1, ref2, ref3; | |
| // addresses to the memory with the referecne signal | |
| reg [8:0] refaddr, // refaddr is decremented by two | |
| refaddrm1; // this is refaddr minus 1, also decremented by two. | |
| //########################################### /TO BE FIXED ###################################### | |
| */ | |
| //######################################### NEW AND FIXED REF MEMORY ACCESS | |
| // addresses to the memory with the referecne signal | |
| //reg [8:0] refaddr, // refaddr is decremented by two | |
| // refaddrm1; // this is refaddr minus 1, also decremented by two. | |
| // Registers to read two 32-bit words (two samples each) | |
| //wire [31:0] ref01, ref23; | |
| // The four data samples read from the reference signal | |
| // These must be signed for the implementation of the multiplication: | |
| wire signed [15:0] ref0, ref1, ref2, ref3; | |
| // read the reference signal: | |
| //assign ref23 = ref_sigm1; | |
| //assign ref01 = ref_sig; | |
| //assign refaddr_rx = refaddr; | |
| //assign refaddrm1_rx = refaddrm1; | |
| assign ref0 = ref_sig[15:0]; | |
| assign ref1 = ref_sig[31:16]; | |
| assign ref2 = ref_sigm1[15:0]; | |
| assign ref3 = ref_sigm1[31:16]; | |
| //##################################### /NEW AND FIXED REF MEMORY ACCESS ##################### | |
| reg busy; | |
| //http://www.asic-world.com/tidbits/verilog_fsm.html <<--- Como implementar uma maquina de estados em condições | |
| parameter IDLE = 2'b00; | |
| parameter CORR = 2'b10; | |
| parameter START = 2'b11; | |
| reg [1:0] state; | |
| wire [1:0] next_state; | |
| assign next_state = fsm_function(state, DIN_RDY, busy); | |
| function [1:0] fsm_function(input [1:0] state, | |
| input DIN_RDY, | |
| input busy); | |
| case(state) | |
| IDLE: if(DIN_RDY==1'b1) fsm_function = START; else fsm_function = IDLE; | |
| START: if(DIN_RDY==1'b1) fsm_function = START; else fsm_function = CORR; | |
| CORR: if(busy) fsm_function = CORR; else fsm_function = IDLE; | |
| default: fsm_function = IDLE; | |
| endcase | |
| endfunction | |
| always @ (posedge clock) begin | |
| if (reset) state <= IDLE; | |
| else state <= next_state; | |
| end | |
| wire [9:0] counter_max = (Nsamples >> 2)+2; | |
| reg [9:0] counter; | |
| assign readaddr = counter; // read address for the circular buffer related to the counter | |
| //And do something | |
| always @ (posedge clock) begin | |
| if (reset) begin | |
| busy <= 0; | |
| counter <= 0; | |
| correlation <= 42'd0; | |
| corr_rdy <= 0; | |
| refaddr <= (Nsamples >> 1); | |
| refaddrm1 <= (Nsamples >> 1)-1; | |
| end | |
| else begin | |
| case (state) | |
| IDLE: begin | |
| counter <= 0; | |
| corr_rdy <= 0; | |
| refaddr <= (Nsamples >> 1); | |
| refaddrm1 <= (Nsamples >> 1)-1; | |
| end | |
| START: begin | |
| //Load last correlation | |
| corrout <= correlation[41] ? -correlation : correlation; | |
| corr_rdy <= 1; | |
| //This make it keep on this state | |
| busy <= 1'b1; | |
| //Increment the adress for the audio memory | |
| counter <= counter +1; | |
| //Reset correlation | |
| //correlation <= ref0 * audio0 + ref1 * audio1 + ref2 * audio2 + ref3 * audio3; | |
| // decrement the addresses of the reference memory: | |
| refaddr <= refaddr - 2; | |
| refaddrm1 <= refaddrm1 - 2; | |
| correlation <= 42'd0; | |
| end | |
| CORR: begin | |
| //$display("CORR"); | |
| if (counter>=counter_max) busy <= 1'b0; //This makes next state be IDLE | |
| else begin | |
| //update correlation value | |
| correlation <= correlation + ref0 * audio0 + ref1 * audio1 + ref2 * audio2 + ref3 * audio3; | |
| corr_rdy <= 0; | |
| //This make it keep on this state | |
| busy <= 1'b1; | |
| //Increment the adress for the audio memory | |
| counter <= counter +1; | |
| // decrement the addresses of the reference memory: | |
| refaddr <= refaddr - 2; | |
| refaddrm1 <= refaddrm1 - 2; | |
| if (counter>=(counter_max-2)) busy <= 1'b0; | |
| end | |
| end | |
| //TODO: check default and etc | |
| endcase | |
| end | |
| end | |
| endmodule |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment