module oscilloscope ( input wire clock, frame, reset, input wire cfg_data, input wire trg_flag, input wire [63: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 [63:0] osc_data_reg, osc_data_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 [1:0]; reg [19:0] int_cntr_next [1: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 [2:0]; reg [17:0] ram_data_next [2:0]; 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[2][j] : 1'bz; end endgenerate always @(posedge clock) begin if (reset) begin osc_data_reg <= 64'd0; ram_addr_reg <= 20'd0; bus_miso_reg <= 16'd0; bus_busy_reg <= 1'b0; int_case_reg <= 5'd0; int_cntr_reg[0] <= 20'd0; int_cntr_reg[1] <= 20'd0; int_trig_reg <= 1'b0; int_trig_addr_reg <= 20'd0; for(i = 0; i <= 2; i = i + 1) begin ram_wren_reg[i] <= 1'b0; ram_data_reg[i] <= 16'd0; end end else begin osc_data_reg <= osc_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[0] <= int_cntr_next[0]; int_cntr_reg[1] <= int_cntr_next[1]; int_trig_reg <= int_trig_next; int_trig_addr_reg <= int_trig_addr_next; for(i = 0; i <= 2; i = i + 1) begin ram_wren_reg[i] <= ram_wren_next[i]; ram_data_reg[i] <= ram_data_next[i]; end end end always @* begin osc_data_next = osc_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[0] = int_cntr_reg[0]; int_cntr_next[1] = int_cntr_reg[1]; int_trig_next = int_trig_reg; int_trig_addr_next = int_trig_addr_reg; for(i = 0; i < 2; i = i + 1) begin ram_wren_next[i+1] = ram_wren_reg[i]; ram_data_next[i+1] = ram_data_reg[i]; end ram_wren_next[0] = 1'b0; ram_data_next[0] = 18'd0; case (int_case_reg) 0: begin bus_busy_next = 1'b0; int_cntr_next[0] = 20'd0; int_cntr_next[1] = 20'd0; int_trig_next = 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; ram_data_next[0] = {bus_mosi[15:8], 1'b0, bus_mosi[7:0], 1'b0}; end else begin ram_addr_next = int_trig_addr_reg + bus_addr; // ram_addr_next = bus_addr; end end else if (cfg_data) begin // start recording ram_wren_next[0] = 1'b1; ram_data_next[0] = 18'd0; ram_addr_next = 20'd0; bus_busy_next = 1'b1; int_case_next = 3'd1; int_trig_addr_next = 20'd0; // int_cntr_next[0] = {cfg_data[7:0], 10'd0}; int_cntr_next[0] = 20'd262143; // int_cntr_next[1] = {cfg_data[15:8], 10'd0}; int_cntr_next[1] = 20'd5000; end end // write zeros 1: begin ram_wren_next[0] = 1'b1; ram_data_next[0] = 18'd2; if(&ram_addr_reg) begin int_case_next = 3'd2; end else begin ram_addr_next = ram_addr_reg + 20'd1; end end // sample recording 2: begin if (frame) begin osc_data_next = osc_data; ram_addr_next = ram_addr_reg + 20'd1; ram_wren_next[0] = 1'b1; ram_data_next[0] = {osc_data[15:8], 1'b0, osc_data[7:0], 1'b0}; int_case_next = 3'd3; if (|int_cntr_reg[1]) begin int_cntr_next[0] = int_cntr_reg[0] - 20'd1; int_cntr_next[1] = int_cntr_reg[1] - 20'd1; end else if (int_trig_reg) begin if (|int_cntr_reg[0]) begin int_cntr_next[0] = int_cntr_reg[0] - 20'd1; end end else if (trg_flag) begin int_trig_next = 1'b1; int_trig_addr_next = ram_addr_reg - 20'd19999; end end end 3: begin ram_addr_next = ram_addr_reg + 20'd1; ram_wren_next[0] = 1'b1; ram_data_next[0] = {osc_data_reg[31:24], 1'b0, osc_data_reg[23:16], 1'b0}; int_case_next = 3'd4; end 4: begin ram_addr_next = ram_addr_reg + 20'd1; ram_wren_next[0] = 1'b1; ram_data_next[0] = {osc_data_reg[47:40], 1'b0, osc_data_reg[39:32], 1'b0}; int_case_next = 3'd5; end 5: begin ram_addr_next = ram_addr_reg + 20'd1; ram_wren_next[0] = 1'b1; ram_data_next[0] = {osc_data_reg[63:56], 1'b0, osc_data_reg[55:48], 1'b0}; if (|int_cntr_reg[0]) begin int_case_next = 3'd2; end else begin int_case_next = 3'd0; end end endcase end assign bus_miso = bus_miso_reg; assign bus_busy = bus_busy_reg; endmodule