/* Copyright 2009 DJ Delorie Released under the terms of the GNU General Public License, either version 2 or, at your choice, any later version. http://www.delorie.com/electronics/sdram/ */ `timescale 1ns / 1ps module logic_analyzer ( reset, clock0, clock1, mcu_cs, mcu_nwrl, mcu_nwrh, mcu_nrd, mcu_ready, mcu_addr, mcu_data, trigger, samples0, samples1 ); input reset; input clock0; input clock1; input mcu_cs; input mcu_nwrl; input mcu_nwrh; input mcu_nrd; output mcu_ready; input [23:0] mcu_addr; inout [15:0] mcu_data; input trigger; input [35:0] samples0; input [35:0] samples1; reg mcu_data_write; reg [15:0] mcu_data_c; reg [15:0] sample_counter; reg [15:0] sample_counter_b; reg [15:0] trigger_counter; reg [15:0] trigger_position; reg [15:0] status; wire s_running = status[0]; wire s_trigger = status[1]; wire s_reset = status[2] | reset; wire trigger_any = s_trigger | trigger; wire mcu_nwr = mcu_nwrl & mcu_nwrh; assign mcu_data = mcu_data_write ? mcu_data_c : 16'bzzzzzzzzzzzzzzzz; // We can store two banks of 512 samples of 36 bits. That's 9 bits of // address. We need two address bits to select a 16-bit word from the // sample and one for aliasing. // 14 13 12:4 3 2 1 0 // [control:1] [alias:1] [sample:9] [bank:1] [word:2] [byte] reg ena; wire enb = 1; reg [8:0] addrb; wire web = 0; wire clkb = clock0; wire ssrb = 0; wire [31:0] dob0; wire [3:0] dopb0; wire [31:0] dob1; wire [3:0] dopb1; RAMB16_S36_S36 la_ram0 ( .WEA(1), .ENA(ena), .SSRA(0), .CLKA(clock0), .ADDRA(sample_counter[8:0]), .DIA(samples0[31:0]), .DIPA(samples0[35:32]), .WEB(web), .ENB(enb), .SSRB(ssrb), .CLKB(clkb), .ADDRB(addrb), .DIB(0), .DIPB(0), .DOPB(dopb0), .DOB(dob0) ); RAMB16_S36_S36 la_ram1 ( .WEA(1), .ENA(ena), .SSRA(0), .CLKA(clock1), .ADDRA(sample_counter_b[8:0]), .DIA(samples1[31:0]), .DIPA(samples1[35:32]), .WEB(web), .ENB(enb), .SSRB(ssrb), .CLKB(clkb), .ADDRB(addrb), .DIB(0), .DIPB(0), .DOPB(dopb1), .DOB(dob1) ); assign mcu_ready = 1; reg [15:0] new_sample_counter; reg [15:0] new_sample_counter_b; always @(sample_counter or s_reset or ena) begin if (s_reset) new_sample_counter = 0; else if (ena) new_sample_counter = sample_counter + 1; else new_sample_counter = sample_counter; end always @(sample_counter_b or s_reset or ena) begin if (s_reset) new_sample_counter_b = 0; else if (ena) new_sample_counter_b = sample_counter_b + 1; else new_sample_counter_b = sample_counter_b; end always @(posedge trigger_any or posedge s_running) begin if (s_running) begin ena <= 1; end else begin ena <= 0; trigger_position <= sample_counter_b; end end // We're clocking the two BRAMs on effectively alternate phases. // However, since we reset synchronously with clock1, clock0 is the first // one to increment, so it needs to be the LSB. always @(posedge clock0) begin sample_counter <= new_sample_counter; end always @(posedge clock1) begin sample_counter_b <= new_sample_counter_b; end always @(posedge clock1) begin addrb <= mcu_addr[12:4]; mcu_data_c <= 16'bzzzzzzzzzzzzzzzz; mcu_data_write = 0; if (~mcu_cs & ~mcu_nrd) begin mcu_data_write = 1; if (mcu_addr[14]) begin // high addresses = control registers case (mcu_addr[2:1]) 0: mcu_data_c <= {sample_counter_b[14:0], 1'b0}; 1: mcu_data_c <= {trigger_counter[14:0], 1'b0}; 2: mcu_data_c <= {trigger_position[14:0], 1'b0}; 3: mcu_data_c <= status; endcase end else begin // low addresses = sample memory case (mcu_addr[3:1]) 0: mcu_data_c <= dob1[15:0]; 1: mcu_data_c <= dob1[31:16]; 2: mcu_data_c <= { 12'h0, dopb1 }; 3: mcu_data_c <= mcu_addr[15:0]; 4: mcu_data_c <= dob0[15:0]; 5: mcu_data_c <= dob0[31:16]; 6: mcu_data_c <= { 12'h0, dopb0 }; 7: mcu_data_c <= mcu_addr[15:0]; endcase end end if (~mcu_cs & ~mcu_nwr) begin if (mcu_addr[14]) begin // high addresses = control registers case (mcu_addr[2:1]) //0: sample_counter <= mcu_data; 1: trigger_counter <= {1'b0, mcu_data[15:1]}; //2: trigger_position <= mcu_data; 3: status <= mcu_data; endcase end end // if (~mcu_cs & ~mcu_nwr) end endmodule // logic_analyzer