module oscilloscope ( input wire clock, frame, reset, input wire [16:0] cfg_data, input wire trg_flag, input wire [47:0] osc_data, output wire ram_wren, output wire [19:0] ram_addr, inout wire [17:0] ram_data, input wire bus_ssel, bus_wren, input wire [19:0] bus_addr, input wire [15:0] bus_mosi, output wire [15:0] bus_miso, output wire bus_busy ); reg [47:0] osc_data_reg, osc_data_next; reg [19:0] cfg_cntr_max_reg, cfg_cntr_max_next; reg [19:0] cfg_cntr_mid_reg, cfg_cntr_mid_next; reg [2:0] int_case_reg, int_case_next; reg int_trig_reg, int_trig_next; reg [19:0] int_trig_addr_reg, int_trig_addr_next; reg [19:0] int_cntr_reg, int_cntr_next; reg [15:0] bus_mosi_reg [2:0]; reg [15:0] bus_mosi_next [2:0]; reg [15:0] bus_miso_reg, bus_miso_next; reg bus_busy_reg, bus_busy_next; reg ram_wren_reg [2:0]; reg ram_wren_next [2:0]; reg [17:0] ram_data_reg, ram_data_next; reg [19:0] ram_addr_reg, ram_addr_next; wire [17:0] ram_wren_wire; assign ram_wren = ~ram_wren_reg[0]; assign ram_addr = ram_addr_reg; integer i; genvar j; generate for (j = 0; j < 18; j = j + 1) begin : SRAM_WREN assign ram_wren_wire[j] = ram_wren_reg[2]; assign ram_data[j] = ram_wren_wire[j] ? ram_data_reg[j] : 1'bz; end endgenerate always @(posedge clock) begin if (reset) begin osc_data_reg <= 48'd0; ram_data_reg <= 18'd0; ram_addr_reg <= 20'd0; bus_miso_reg <= 16'd0; bus_busy_reg <= 1'b0; int_case_reg <= 5'd0; int_cntr_reg <= 20'd0; int_trig_reg <= 1'b0; int_trig_addr_reg <= 20'd0; cfg_cntr_max_reg <= 20'd0; cfg_cntr_mid_reg <= 20'd0; for(i = 0; i <= 2; i = i + 1) begin ram_wren_reg[i] <= 1'b0; bus_mosi_reg[i] <= 16'd0; end end else begin osc_data_reg <= osc_data_next; ram_data_reg <= ram_data_next; ram_addr_reg <= ram_addr_next; bus_miso_reg <= bus_miso_next; bus_busy_reg <= bus_busy_next; int_case_reg <= int_case_next; int_cntr_reg <= int_cntr_next; int_trig_reg <= int_trig_next; int_trig_addr_reg <= int_trig_addr_next; cfg_cntr_max_reg <= cfg_cntr_max_next; cfg_cntr_mid_reg <= cfg_cntr_mid_next; for(i = 0; i <= 2; i = i + 1) begin ram_wren_reg[i] <= ram_wren_next[i]; bus_mosi_reg[i] <= bus_mosi_next[i]; end end end always @* begin osc_data_next = osc_data_reg; ram_data_next = ram_data_reg; ram_addr_next = ram_addr_reg; bus_miso_next = bus_miso_reg; bus_busy_next = bus_busy_reg; int_case_next = int_case_reg; int_cntr_next = int_cntr_reg; int_trig_next = int_trig_reg; int_trig_addr_next = int_trig_addr_reg; cfg_cntr_max_next = cfg_cntr_max_reg; cfg_cntr_mid_next = cfg_cntr_mid_reg; for(i = 0; i < 2; i = i + 1) begin ram_wren_next[i+1] = ram_wren_reg[i]; bus_mosi_next[i+1] = bus_mosi_reg[i]; end ram_wren_next[0] = 1'b0; bus_mosi_next[0] = 16'd0; case (int_case_reg) 0: begin ram_data_next = 18'd0; ram_addr_next = 20'd0; bus_busy_next = 1'b0; int_cntr_next = 20'd0; int_trig_next = 1'b0; ram_data_next = {bus_mosi_reg[1][15:8], 1'b0, bus_mosi_reg[1][7:0], 1'b0}; if (bus_ssel) begin bus_miso_next = {ram_data[17:10], ram_data[8:1]}; ram_wren_next[0] = bus_wren; if (bus_wren) begin ram_addr_next = bus_addr; bus_mosi_next[0] = bus_mosi; end else begin // ram_addr_next = int_trig_addr_reg + bus_addr; ram_addr_next = bus_addr; end end else if (cfg_data[16]) begin // start recording ram_wren_next[0] = 1'b1; bus_busy_next = 1'b1; int_case_next = 3'd1; int_trig_addr_next = 20'd0; cfg_cntr_max_next = {cfg_data[7:0], 10'd0}; cfg_cntr_mid_next = {cfg_data[15:8], 10'd0}; end end // sample recording 1: begin ram_wren_next[0] = 1'b1; if (frame) begin osc_data_next = osc_data; ram_addr_next = ram_addr_reg + 20'd1; int_case_next = 3'd2; if ((~int_trig_reg) & (trg_flag) & (int_cntr_reg == cfg_cntr_mid_reg)) begin int_trig_next = 1'b1; int_trig_addr_next = ram_addr_reg; end if (int_trig_reg | (int_cntr_reg < cfg_cntr_mid_reg)) begin int_cntr_next = int_cntr_reg + 20'd1; end end end 2: begin ram_wren_next[0] = 1'b1; ram_data_next = {osc_data_reg[15:8], 1'b0, osc_data_reg[7:0], 1'b0}; ram_addr_next = ram_addr_reg + 20'd1; int_case_next = 3'd3; end 3: begin ram_wren_next[0] = 1'b1; ram_data_next = {osc_data_reg[31:24], 1'b0, osc_data_reg[23:16], 1'b0}; ram_addr_next = ram_addr_reg + 20'd1; int_case_next = 3'd4; end 4: begin ram_wren_next[0] = 1'b1; ram_data_next = {osc_data_reg[47:40], 1'b0, osc_data_reg[39:32], 1'b0}; int_case_next = 3'd1; if (int_cntr_reg >= cfg_cntr_max_reg) begin ram_wren_next[0] = 1'b0; ram_addr_next = 20'd0; int_case_next = 3'd0; end end endcase end assign bus_miso = bus_miso_reg; assign bus_busy = bus_busy_reg; endmodule