Files
kernels/hw/rtl/libs/VX_scope.v
2020-06-06 01:52:44 -04:00

87 lines
1.7 KiB
Verilog

module VX_scope #(
parameter DATAW = 64,
parameter BUSW = 64,
parameter SIZE = 1024
) (
input wire clk,
input wire reset,
input wire start,
input wire [DATAW-1:0] data_in,
input wire [BUSW-1:0] bus_in,
output wire [BUSW-1:0] bus_out,
input wire bus_write,
input wire bus_read
);
reg [DATAW-1:0] mem [SIZE-1:0];
reg [`CLOG2(SIZE)-1:0] raddr, waddr;
reg started, running, done;
reg [BUSW-1:0] delay_cntr;
reg data_valid, data_end;
reg [`LOG2UP(DATAW)-1:0] read_offset;
wire [BUSW-3:0] data_part;
always @(posedge clk) begin
if (reset) begin
raddr <= 0;
waddr <= 0;
started <= 0;
running <= 0;
done <= 0;
delay_cntr <= 0;
read_offset <= 0;
end else begin
if (bus_write) begin
delay_cntr <= bus_in;
end
if (start) begin
started <= 1;
end
if (start || started) begin
if (0 == delay_cntr) begin
running <= 1;
end else begin
delay_cntr <= delay_cntr - 1;
end
end
if (running && !done) begin
mem[waddr] <= data_in;
waddr <= waddr + 1;
if (waddr == $bits(waddr)'(SIZE-1)) begin
done <= 1;
end
end
if (bus_read) begin
if (DATAW > (BUSW-2)) begin
if (read_offset < $bits(read_offset)'(DATAW-(BUSW-2))) begin
read_offset <= read_offset + $bits(read_offset)'(BUSW-2);
end else begin
read_offset <= 0;
raddr <= raddr + 1;
end
end else begin
raddr <= raddr + 1;
end
end
end
end
assign data_valid = (waddr != 0) && (raddr <= waddr);
assign data_end = (0 == read_offset) || (raddr == waddr);
assign data_part = (BUSW-2)'(mem[raddr] >> read_offset);
assign bus_out = {data_valid, data_end, data_part};
endmodule