refactor logic analyzer into submodules
This commit is contained in:
parent
fade794333
commit
11495fca61
2
Makefile
2
Makefile
|
|
@ -11,7 +11,7 @@ lint:
|
|||
sim: bit_fifo_tb bridge_rx_tb bridge_tx_tb fifo_tb lut_ram_tb uart_tx_tb
|
||||
|
||||
logic_analyzer_tb:
|
||||
iverilog -g2012 -o sim.out test/logic_analyzer_tb.sv src/manta/logic_analyzer.v src/manta/fifo.v src/manta/trigger.v src/manta/xilinx_true_dual_port_read_first_2_clock_ram.v
|
||||
iverilog -g2012 -o sim.out test/logic_analyzer_tb.sv src/manta/logic_analyzer.v src/manta/la_fsm.v src/manta/trigger_block.v src/manta/trigger.v src/manta/sample_mem.v src/manta/xilinx_true_dual_port_read_first_2_clock_ram.v
|
||||
vvp sim.out
|
||||
rm sim.out
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,11 @@ module fifo (
|
|||
reg [AW:0] write_pointer;
|
||||
reg [AW:0] read_pointer;
|
||||
|
||||
initial begin
|
||||
write_pointer = 0;
|
||||
read_pointer = 0;
|
||||
end
|
||||
|
||||
reg empty_int;
|
||||
assign empty_int = (write_pointer[AW] == read_pointer[AW]);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,117 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module la_fsm(
|
||||
input wire clk,
|
||||
|
||||
input wire trig,
|
||||
input wire [$clog2(SAMPLE_DEPTH):0] fifo_size,
|
||||
output reg fifo_acquire,
|
||||
output reg fifo_pop,
|
||||
|
||||
// input port
|
||||
input wire [15:0] addr_i,
|
||||
input wire [15:0] wdata_i,
|
||||
input wire [15:0] rdata_i,
|
||||
input wire rw_i,
|
||||
input wire valid_i,
|
||||
|
||||
// output port
|
||||
output reg [15:0] addr_o,
|
||||
output reg [15:0] wdata_o,
|
||||
output reg [15:0] rdata_o,
|
||||
output reg rw_o,
|
||||
output reg valid_o);
|
||||
|
||||
parameter BASE_ADDR = 0;
|
||||
parameter SAMPLE_DEPTH = 0;
|
||||
|
||||
// state machine
|
||||
localparam IDLE = 0;
|
||||
localparam MOVE_TO_POSITION = 1;
|
||||
localparam IN_POSITION = 2;
|
||||
localparam FILLING_BUFFER = 3;
|
||||
localparam FILLED = 4;
|
||||
|
||||
reg [3:0] state;
|
||||
reg signed [15:0] trigger_loc;
|
||||
reg signed [15:0] present_loc;
|
||||
|
||||
initial state = IDLE;
|
||||
initial trigger_loc = 0;
|
||||
initial present_loc = 0;
|
||||
|
||||
// perform register operations
|
||||
always @(posedge clk) begin
|
||||
addr_o <= addr_i;
|
||||
wdata_o <= wdata_i;
|
||||
rdata_o <= rdata_i;
|
||||
rw_o <= rw_i;
|
||||
valid_o <= valid_i;
|
||||
|
||||
// check if address is valid
|
||||
if( (valid_i) && (addr_i >= BASE_ADDR) && (addr_i <= BASE_ADDR + 2)) begin
|
||||
|
||||
if(!rw_i) begin // reads
|
||||
case (addr_i)
|
||||
BASE_ADDR + 0: rdata_o <= state;
|
||||
BASE_ADDR + 1: rdata_o <= trigger_loc;
|
||||
BASE_ADDR + 2: rdata_o <= present_loc;
|
||||
endcase
|
||||
end
|
||||
|
||||
else begin // writes
|
||||
case (addr_i)
|
||||
BASE_ADDR + 0: state <= wdata_i;
|
||||
BASE_ADDR + 1: trigger_loc <= wdata_i;
|
||||
BASE_ADDR + 2: present_loc <= wdata_i;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// run state machine
|
||||
always @(posedge clk) begin
|
||||
if(state == IDLE) begin
|
||||
present_loc <= (trigger_loc < 0) ? trigger_loc : 0;
|
||||
end
|
||||
|
||||
else if(state == MOVE_TO_POSITION) begin
|
||||
// if trigger location is negative or zero,
|
||||
// then we're already in position
|
||||
if(trigger_loc <= 0) state <= IN_POSITION;
|
||||
|
||||
// otherwise we'll need to wait a little,
|
||||
// but we'll need to buffer along the way
|
||||
else begin
|
||||
present_loc <= present_loc + 1;
|
||||
// add code to add samples to word FIFO
|
||||
fifo_acquire <= 1;
|
||||
if (present_loc == trigger_loc) state <= IN_POSITION;
|
||||
end
|
||||
end
|
||||
|
||||
else if(state == IN_POSITION) begin
|
||||
// pop stuff out of the word FIFO in addition to pulling it in
|
||||
fifo_acquire <= 1;
|
||||
fifo_pop <= 1;
|
||||
|
||||
if(trig) state <= FILLING_BUFFER;
|
||||
end
|
||||
|
||||
else if(state == FILLING_BUFFER) begin
|
||||
fifo_acquire <= 1;
|
||||
fifo_pop <= 0;
|
||||
if(fifo_size == SAMPLE_DEPTH) state <= FILLED;
|
||||
end
|
||||
|
||||
else if(state == FILLED) begin
|
||||
// don't automatically go back to IDLE, the host will move
|
||||
// the state to MOVE_TO_POSITION
|
||||
|
||||
present_loc <= (trigger_loc < 0) ? trigger_loc : 0;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -26,201 +26,98 @@ module logic_analyzer(
|
|||
);
|
||||
|
||||
parameter BASE_ADDR = 0;
|
||||
parameter SAMPLE_DEPTH = 4096;
|
||||
parameter SAMPLE_DEPTH = 0;
|
||||
|
||||
// trigger configuration registers
|
||||
// - each probe gets an operation and a compare register
|
||||
// - at the end we AND them all together. along with any custom probes the user specs
|
||||
|
||||
reg [3:0] larry_trigger_op;
|
||||
reg larry_trigger_arg;
|
||||
reg larry_trig;
|
||||
trigger #(.INPUT_WIDTH(1)) larry_trigger(
|
||||
// fsm
|
||||
la_fsm #(.BASE_ADDR(BASE_ADDR), .SAMPLE_DEPTH(SAMPLE_DEPTH)) fsm (
|
||||
.clk(clk),
|
||||
|
||||
.probe(larry),
|
||||
.op(larry_trigger_op),
|
||||
.arg(larry_trigger_arg),
|
||||
.trig(larry_trig));
|
||||
.trig(trig),
|
||||
.fifo_size(fifo_size),
|
||||
.fifo_acquire(fifo_acquire),
|
||||
.fifo_pop(fifo_pop),
|
||||
|
||||
reg [3:0] curly_trigger_op;
|
||||
reg curly_trigger_arg;
|
||||
reg curly_trig;
|
||||
trigger #(.INPUT_WIDTH(1)) curly_trigger(
|
||||
.clk(clk),
|
||||
.addr_i(addr_i),
|
||||
.wdata_i(wdata_i),
|
||||
.rdata_i(rdata_i),
|
||||
.rw_i(rw_i),
|
||||
.valid_i(valid_i),
|
||||
|
||||
.probe(curly),
|
||||
.op(curly_trigger_op),
|
||||
.arg(curly_trigger_arg),
|
||||
.trig(curly_trig));
|
||||
|
||||
|
||||
reg [3:0] moe_trigger_op;
|
||||
reg moe_trigger_arg;
|
||||
reg moe_trig;
|
||||
trigger #(.INPUT_WIDTH(1)) moe_trigger(
|
||||
.clk(clk),
|
||||
|
||||
.probe(moe),
|
||||
.op(moe_trigger_op),
|
||||
.arg(moe_trigger_arg),
|
||||
.trig(moe_trig));
|
||||
|
||||
reg [3:0] shemp_trigger_op;
|
||||
reg [3:0] shemp_trigger_arg;
|
||||
reg shemp_trig;
|
||||
trigger #(.INPUT_WIDTH(4)) shemp_trigger(
|
||||
.clk(clk),
|
||||
|
||||
.probe(shemp),
|
||||
.op(shemp_trigger_op),
|
||||
.arg(shemp_trigger_arg),
|
||||
.trig(shemp_trig));
|
||||
|
||||
reg triggered;
|
||||
assign triggered = larry_trig || curly_trig || moe_trig || shemp_trig;
|
||||
|
||||
reg [6:0] concatenated;
|
||||
assign concatenated = {larry, curly, moe, shemp};
|
||||
.addr_o(fsm_trig_blk_addr),
|
||||
.wdata_o(fsm_trig_blk_wdata),
|
||||
.rdata_o(fsm_trig_blk_rdata),
|
||||
.rw_o(fsm_trig_blk_rw),
|
||||
.valid_o(fsm_trig_blk_valid));
|
||||
|
||||
// word-wise fifo
|
||||
fifo #(.WIDTH(FIFO_WIDTH), .DEPTH(SAMPLE_DEPTH)) wfifo(
|
||||
reg [15:0] fsm_trig_blk_addr;
|
||||
reg [15:0] fsm_trig_blk_wdata;
|
||||
reg [15:0] fsm_trig_blk_rdata;
|
||||
reg fsm_trig_blk_rw;
|
||||
reg fsm_trig_blk_valid;
|
||||
|
||||
reg trig;
|
||||
reg [$clog2(SAMPLE_DEPTH):0] fifo_size;
|
||||
reg fifo_acquire;
|
||||
reg fifo_pop;
|
||||
|
||||
|
||||
// trigger block
|
||||
trigger_block #(.BASE_ADDR(BASE_ADDR + 2)) trig_blk(
|
||||
.clk(clk),
|
||||
.bram_rst(1'b0),
|
||||
|
||||
.in(concatenated),
|
||||
.in_valid(wfifo_in_valid),
|
||||
|
||||
.out(wfifo_out),
|
||||
.out_req(wfifo_out_req),
|
||||
.out_valid(wfifo_out_valid),
|
||||
|
||||
.size(wfifo_size),
|
||||
.empty(),
|
||||
.full());
|
||||
.larry(larry),
|
||||
.curly(curly),
|
||||
.moe(moe),
|
||||
.shemp(shemp),
|
||||
|
||||
reg wfifo_in_valid;
|
||||
localparam FIFO_WIDTH = 7;
|
||||
reg [FIFO_WIDTH-1:0] wfifo_out;
|
||||
reg wfifo_out_req;
|
||||
reg wfifo_out_valid;
|
||||
.trig(trig),
|
||||
|
||||
.addr_i(fsm_trig_blk_addr),
|
||||
.wdata_i(fsm_trig_blk_wdata),
|
||||
.rdata_i(fsm_trig_blk_rdata),
|
||||
.rw_i(fsm_trig_blk_rw),
|
||||
.valid_i(fsm_trig_blk_valid),
|
||||
|
||||
reg [$clog2(SAMPLE_DEPTH):0] wfifo_size;
|
||||
.addr_o(trig_blk_sample_mem_addr),
|
||||
.wdata_o(trig_blk_sample_mem_wdata),
|
||||
.rdata_o(trig_blk_sample_mem_rdata),
|
||||
.rw_o(trig_blk_sample_mem_rw),
|
||||
.valid_o(trig_blk_sample_mem_valid));
|
||||
|
||||
|
||||
// state machine
|
||||
localparam IDLE = 0;
|
||||
localparam START = 1;
|
||||
localparam MOVE_TO_POSITION = 2;
|
||||
localparam IN_POSITION = 3;
|
||||
localparam FILLING_BUFFER = 4;
|
||||
localparam FILLED = 5;
|
||||
reg [15:0] trig_blk_sample_mem_addr;
|
||||
reg [15:0] trig_blk_sample_mem_wdata;
|
||||
reg [15:0] trig_blk_sample_mem_rdata;
|
||||
reg trig_blk_sample_mem_rw;
|
||||
reg trig_blk_sample_mem_valid;
|
||||
|
||||
reg [3:0] state;
|
||||
initial state = IDLE;
|
||||
// sample memory
|
||||
sample_mem #(.BASE_ADDR(BASE_ADDR + 10), .SAMPLE_DEPTH(SAMPLE_DEPTH)) sample_mem(
|
||||
.clk(clk),
|
||||
|
||||
reg signed [15:0] trigger_loc;
|
||||
initial trigger_loc = 0;
|
||||
// fifo
|
||||
.acquire(fifo_acquire),
|
||||
.pop(fifo_pop),
|
||||
.size(fifo_size),
|
||||
|
||||
reg signed [15:0] present_loc;
|
||||
initial present_loc = 0;
|
||||
// probes
|
||||
.larry(larry),
|
||||
.curly(curly),
|
||||
.moe(moe),
|
||||
.shemp(shemp),
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(state == IDLE) begin
|
||||
present_loc <= (trigger_loc < 0) ? trigger_loc : 0;
|
||||
end
|
||||
// input port
|
||||
.addr_i(trig_blk_sample_mem_addr),
|
||||
.wdata_i(trig_blk_sample_mem_wdata),
|
||||
.rdata_i(trig_blk_sample_mem_rdata),
|
||||
.rw_i(trig_blk_sample_mem_rw),
|
||||
.valid_i(trig_blk_sample_mem_valid),
|
||||
|
||||
else if(state == MOVE_TO_POSITION) begin
|
||||
// if trigger location is negative or zero,
|
||||
// then we're already in position
|
||||
if(trigger_loc <= 0) state <= IN_POSITION;
|
||||
|
||||
// otherwise we'll need to wait a little,
|
||||
// but we'll need to buffer along the way
|
||||
else begin
|
||||
present_loc <= present_loc + 1;
|
||||
// add code to add samples to word FIFO
|
||||
wfifo_in_valid <= 1;
|
||||
if (present_loc == trigger_loc) state <= IN_POSITION;
|
||||
end
|
||||
end
|
||||
|
||||
else if(state == IN_POSITION) begin
|
||||
// pop stuff out of the word FIFO in addition to pulling it in
|
||||
wfifo_in_valid <= 1;
|
||||
wfifo_out_req <= 1;
|
||||
|
||||
if(triggered) state <= FILLING_BUFFER;
|
||||
end
|
||||
|
||||
else if(state == FILLING_BUFFER) begin
|
||||
if(wfifo_size == SAMPLE_DEPTH) state <= FILLED;
|
||||
end
|
||||
|
||||
else if(state == FILLED) begin
|
||||
// don't automatically go back to IDLE, the host will move
|
||||
// the state to MOVE_TO_POSITION
|
||||
|
||||
present_loc <= (trigger_loc < 0) ? trigger_loc : 0;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
// memory servicing
|
||||
// - TODO: add support for comparision values > 16 bits,
|
||||
// we'll have to concat them somwehere up here
|
||||
|
||||
always @(posedge clk) begin
|
||||
|
||||
addr_o <= addr_i;
|
||||
wdata_o <= wdata_i;
|
||||
rdata_o <= rdata_i;
|
||||
rw_o <= rw_i;
|
||||
valid_o <= valid_i;
|
||||
|
||||
// operations to configuration registers
|
||||
if( (addr_i >= BASE_ADDR) && (addr_i <= BASE_ADDR + 9) ) begin
|
||||
|
||||
// reads
|
||||
if(valid_i && !rw_i) begin
|
||||
case (addr_i)
|
||||
BASE_ADDR + 0: rdata_o <= state;
|
||||
BASE_ADDR + 1: rdata_o <= trigger_loc;
|
||||
BASE_ADDR + 2: rdata_o <= larry_trigger_op;
|
||||
BASE_ADDR + 3: rdata_o <= larry_trigger_arg;
|
||||
BASE_ADDR + 4: rdata_o <= curly_trigger_op;
|
||||
BASE_ADDR + 5: rdata_o <= curly_trigger_arg;
|
||||
BASE_ADDR + 6: rdata_o <= moe_trigger_op;
|
||||
BASE_ADDR + 7: rdata_o <= moe_trigger_arg;
|
||||
BASE_ADDR + 8: rdata_o <= shemp_trigger_op;
|
||||
BASE_ADDR + 9: rdata_o <= shemp_trigger_arg;
|
||||
default: rdata_o <= rdata_i;
|
||||
endcase
|
||||
end
|
||||
|
||||
// writes
|
||||
else if(valid_i && rw_i) begin
|
||||
case (addr_i)
|
||||
BASE_ADDR + 0: state <= wdata_i;
|
||||
BASE_ADDR + 1: trigger_loc <= wdata_i;
|
||||
BASE_ADDR + 2: larry_trigger_op <= wdata_i;
|
||||
BASE_ADDR + 3: larry_trigger_arg <= wdata_i;
|
||||
BASE_ADDR + 4: curly_trigger_op <= wdata_i;
|
||||
BASE_ADDR + 5: curly_trigger_arg <= wdata_i;
|
||||
BASE_ADDR + 6: moe_trigger_op <= wdata_i;
|
||||
BASE_ADDR + 7: moe_trigger_arg <= wdata_i;
|
||||
BASE_ADDR + 8: shemp_trigger_op <= wdata_i;
|
||||
BASE_ADDR + 9: shemp_trigger_arg <= wdata_i;
|
||||
default: wdata_o <= wdata_i;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// operations to BRAM
|
||||
else if( (addr_i >= BASE_ADDR + 10) && (addr_i <= BASE_ADDR + 10 + SAMPLE_DEPTH) ) begin
|
||||
end
|
||||
end
|
||||
// output port
|
||||
.addr_o(addr_o),
|
||||
.wdata_o(wdata_o),
|
||||
.rdata_o(rdata_o),
|
||||
.rw_o(rw_o),
|
||||
.valid_o(valid_o));
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module sample_mem(
|
||||
input wire clk,
|
||||
|
||||
// fifo
|
||||
input wire acquire,
|
||||
input wire pop,
|
||||
output wire [AW:0] size,
|
||||
|
||||
// probes
|
||||
input wire larry,
|
||||
input wire curly,
|
||||
input wire moe,
|
||||
input wire [3:0] shemp,
|
||||
|
||||
// input port
|
||||
input wire [15:0] addr_i,
|
||||
input wire [15:0] wdata_i,
|
||||
input wire [15:0] rdata_i,
|
||||
input wire rw_i,
|
||||
input wire valid_i,
|
||||
|
||||
// output port
|
||||
output reg [15:0] addr_o,
|
||||
output reg [15:0] wdata_o,
|
||||
output reg [15:0] rdata_o,
|
||||
output reg rw_o,
|
||||
output reg valid_o);
|
||||
|
||||
parameter BASE_ADDR = 0;
|
||||
parameter SAMPLE_DEPTH = 0;
|
||||
|
||||
// bus controller
|
||||
reg [$clog2(SAMPLE_DEPTH):0] bram_read_addr;
|
||||
reg [15:0] bram_read_data;
|
||||
|
||||
always @(*) begin
|
||||
// if address is valid
|
||||
if ( (addr_i >= BASE_ADDR) && (addr_i <= BASE_ADDR + SAMPLE_DEPTH) ) begin
|
||||
|
||||
// figure out proper place to read from
|
||||
// want to read from the read pointer, and then loop back around
|
||||
if(read_pointer + (addr_i - BASE_ADDR) > SAMPLE_DEPTH)
|
||||
bram_read_addr <= read_pointer + (addr_i - BASE_ADDR) - SAMPLE_DEPTH;
|
||||
|
||||
else
|
||||
bram_read_addr = read_pointer + (addr_i - BASE_ADDR);
|
||||
end
|
||||
|
||||
else bram_read_addr <= 0;
|
||||
end
|
||||
|
||||
|
||||
// pipeline bus to compensate for 2-cycles of delay in BRAM
|
||||
reg [15:0] addr_pip;
|
||||
reg [15:0] wdata_pip;
|
||||
reg [15:0] rdata_pip;
|
||||
reg rw_pip;
|
||||
reg valid_pip;
|
||||
|
||||
always @(posedge clk) begin
|
||||
addr_pip <= addr_i;
|
||||
wdata_pip <= wdata_i;
|
||||
rdata_pip <= rdata_i;
|
||||
rw_pip <= rw_i;
|
||||
valid_pip <= valid_i;
|
||||
|
||||
addr_o <= addr_pip;
|
||||
wdata_o <= wdata_pip;
|
||||
rdata_o <= rdata_pip;
|
||||
rw_o <= rw_pip;
|
||||
valid_o <= valid_pip;
|
||||
|
||||
if( valid_pip && !rw_pip && (addr_pip >= BASE_ADDR) && (addr_pip <= BASE_ADDR + SAMPLE_DEPTH) )
|
||||
rdata_o <= bram_read_data;
|
||||
end
|
||||
|
||||
|
||||
// bram
|
||||
xilinx_true_dual_port_read_first_2_clock_ram #(
|
||||
.RAM_WIDTH(16),
|
||||
.RAM_DEPTH(SAMPLE_DEPTH),
|
||||
.RAM_PERFORMANCE("HIGH_PERFORMANCE")
|
||||
|
||||
) bram (
|
||||
|
||||
// read port (controlled by bus)
|
||||
.clka(clk),
|
||||
.rsta(1'b0),
|
||||
.ena(1'b1),
|
||||
.addra(bram_read_addr),
|
||||
.dina(),
|
||||
.wea(1'b0),
|
||||
.regcea(1'b1),
|
||||
.douta(bram_read_data),
|
||||
|
||||
// write port (controlled by FIFO)
|
||||
.clkb(clk),
|
||||
.rstb(1'b0),
|
||||
.enb(1'b1),
|
||||
.addrb(write_pointer),
|
||||
.dinb({larry, curly, moe, shemp}),
|
||||
.web(acquire),
|
||||
.regceb(1'b1),
|
||||
.doutb());
|
||||
|
||||
|
||||
// fifo
|
||||
localparam AW = $clog2(SAMPLE_DEPTH);
|
||||
|
||||
reg [AW:0] write_pointer = 0;
|
||||
reg [AW:0] read_pointer = 0;
|
||||
|
||||
assign size = write_pointer - read_pointer;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (acquire) write_pointer <= write_pointer + 1'd1;
|
||||
if (pop) read_pointer <= read_pointer + 1'd1;
|
||||
end
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module trigger_block(
|
||||
input wire clk,
|
||||
|
||||
// probes
|
||||
input wire larry,
|
||||
input wire curly,
|
||||
input wire moe,
|
||||
input wire [3:0] shemp,
|
||||
|
||||
// trigger
|
||||
output reg trig,
|
||||
|
||||
// input port
|
||||
input wire [15:0] addr_i,
|
||||
input wire [15:0] wdata_i,
|
||||
input wire [15:0] rdata_i,
|
||||
input wire rw_i,
|
||||
input wire valid_i,
|
||||
|
||||
// output port
|
||||
output reg [15:0] addr_o,
|
||||
output reg [15:0] wdata_o,
|
||||
output reg [15:0] rdata_o,
|
||||
output reg rw_o,
|
||||
output reg valid_o);
|
||||
|
||||
parameter BASE_ADDR = 0;
|
||||
|
||||
// trigger configuration registers
|
||||
// - each probe gets an operation and a compare register
|
||||
// - at the end we OR them all together. along with any custom probes the user specs
|
||||
|
||||
reg [3:0] larry_trigger_op;
|
||||
reg larry_trigger_arg;
|
||||
reg larry_trig;
|
||||
trigger #(.INPUT_WIDTH(1)) larry_trigger(
|
||||
.clk(clk),
|
||||
|
||||
.probe(larry),
|
||||
.op(larry_trigger_op),
|
||||
.arg(larry_trigger_arg),
|
||||
.trig(larry_trig));
|
||||
|
||||
reg [3:0] curly_trigger_op;
|
||||
reg curly_trigger_arg;
|
||||
reg curly_trig;
|
||||
trigger #(.INPUT_WIDTH(1)) curly_trigger(
|
||||
.clk(clk),
|
||||
|
||||
.probe(curly),
|
||||
.op(curly_trigger_op),
|
||||
.arg(curly_trigger_arg),
|
||||
.trig(curly_trig));
|
||||
|
||||
|
||||
reg [3:0] moe_trigger_op;
|
||||
reg moe_trigger_arg;
|
||||
reg moe_trig;
|
||||
trigger #(.INPUT_WIDTH(1)) moe_trigger(
|
||||
.clk(clk),
|
||||
|
||||
.probe(moe),
|
||||
.op(moe_trigger_op),
|
||||
.arg(moe_trigger_arg),
|
||||
.trig(moe_trig));
|
||||
|
||||
reg [3:0] shemp_trigger_op;
|
||||
reg [3:0] shemp_trigger_arg;
|
||||
reg shemp_trig;
|
||||
trigger #(.INPUT_WIDTH(4)) shemp_trigger(
|
||||
.clk(clk),
|
||||
|
||||
.probe(shemp),
|
||||
.op(shemp_trigger_op),
|
||||
.arg(shemp_trigger_arg),
|
||||
.trig(shemp_trig));
|
||||
|
||||
reg triggered;
|
||||
assign triggered = larry_trig || curly_trig || moe_trig || shemp_trig;
|
||||
|
||||
// perform register operations
|
||||
always @(posedge clk) begin
|
||||
addr_o <= addr_i;
|
||||
wdata_o <= wdata_i;
|
||||
rdata_o <= rdata_i;
|
||||
rw_o <= rw_i;
|
||||
valid_o <= valid_i;
|
||||
rdata_o <= rdata_i;
|
||||
|
||||
if( (addr_i >= BASE_ADDR) && (addr_i <= BASE_ADDR + 9) ) begin
|
||||
|
||||
// reads
|
||||
if(valid_i && !rw_i) begin
|
||||
case (addr_i)
|
||||
BASE_ADDR + 0: rdata_o <= larry_trigger_op;
|
||||
BASE_ADDR + 1: rdata_o <= larry_trigger_arg;
|
||||
BASE_ADDR + 2: rdata_o <= curly_trigger_op;
|
||||
BASE_ADDR + 3: rdata_o <= curly_trigger_arg;
|
||||
BASE_ADDR + 4: rdata_o <= moe_trigger_op;
|
||||
BASE_ADDR + 5: rdata_o <= moe_trigger_arg;
|
||||
BASE_ADDR + 6: rdata_o <= shemp_trigger_op;
|
||||
BASE_ADDR + 7: rdata_o <= shemp_trigger_arg;
|
||||
endcase
|
||||
end
|
||||
|
||||
// writes
|
||||
else if(valid_i && rw_i) begin
|
||||
case (addr_i)
|
||||
BASE_ADDR + 0: larry_trigger_op <= wdata_i;
|
||||
BASE_ADDR + 1: larry_trigger_arg <= wdata_i;
|
||||
BASE_ADDR + 2: curly_trigger_op <= wdata_i;
|
||||
BASE_ADDR + 3: curly_trigger_arg <= wdata_i;
|
||||
BASE_ADDR + 4: moe_trigger_op <= wdata_i;
|
||||
BASE_ADDR + 5: moe_trigger_arg <= wdata_i;
|
||||
BASE_ADDR + 6: shemp_trigger_op <= wdata_i;
|
||||
BASE_ADDR + 7: shemp_trigger_arg <= wdata_i;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -5,11 +5,11 @@ module fifo_tb();
|
|||
logic clk;
|
||||
logic rst;
|
||||
|
||||
logic [7:0] data_in;
|
||||
logic input_ready;
|
||||
logic [7:0] in;
|
||||
logic in_valid;
|
||||
|
||||
logic request_output;
|
||||
logic [7:0] data_out;
|
||||
logic out_req;
|
||||
logic [7:0] out;
|
||||
|
||||
logic [11:0] size;
|
||||
logic empty;
|
||||
|
|
@ -17,13 +17,13 @@ module fifo_tb();
|
|||
|
||||
fifo uut (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.bram_rst(rst),
|
||||
|
||||
.data_in(data_in),
|
||||
.input_ready(input_ready),
|
||||
.in(in),
|
||||
.in_valid(in_valid),
|
||||
|
||||
.request_output(request_output),
|
||||
.data_out(data_out),
|
||||
.out_req(out_req),
|
||||
.out(out),
|
||||
|
||||
.size(size),
|
||||
.empty(empty),
|
||||
|
|
@ -39,27 +39,27 @@ module fifo_tb();
|
|||
$dumpvars(0, fifo_tb);
|
||||
clk = 0;
|
||||
rst = 1;
|
||||
data_in = 0;
|
||||
input_ready = 0;
|
||||
request_output = 0;
|
||||
in = 0;
|
||||
in_valid = 0;
|
||||
out_req = 0;
|
||||
#10;
|
||||
rst = 0;
|
||||
#10;
|
||||
|
||||
// try and load some data, make sure counter increases
|
||||
input_ready = 1;
|
||||
in_valid = 1;
|
||||
|
||||
for(int i=0; i < 4097; i++) begin
|
||||
data_in = i;
|
||||
in = i;
|
||||
#10;
|
||||
end
|
||||
|
||||
input_ready = 0;
|
||||
in_valid = 0;
|
||||
|
||||
// try and read out said data
|
||||
request_output = 1;
|
||||
out_req = 1;
|
||||
for(int i=0; i < 4097; i++) begin
|
||||
$display("%h", data_out);
|
||||
$display("%h", out);
|
||||
#10;
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ module logic_analyzer_tb;
|
|||
logic la_tb_valid;
|
||||
|
||||
|
||||
logic_analyzer la(
|
||||
logic_analyzer #(.BASE_ADDR(0), .SAMPLE_DEPTH(128)) la(
|
||||
.clk(clk),
|
||||
|
||||
// probes
|
||||
|
|
@ -107,7 +107,7 @@ module logic_analyzer_tb;
|
|||
tb_la_wdata = 5;
|
||||
#`CP
|
||||
tb_la_valid = 0;
|
||||
#`CP
|
||||
while (!la_tb_valid) #`CP;
|
||||
$display(" -> wrote 0x0005 to state reg (addr 0x0000)");
|
||||
|
||||
// read
|
||||
|
|
@ -118,6 +118,24 @@ module logic_analyzer_tb;
|
|||
while (!la_tb_valid) #`CP;
|
||||
$display(" -> read 0x%h from state reg (addr 0x0000)", la_tb_rdata);
|
||||
|
||||
// write
|
||||
tb_la_addr = 0;
|
||||
tb_la_valid = 1;
|
||||
tb_la_rw = 1;
|
||||
tb_la_wdata = 0;
|
||||
#`CP
|
||||
tb_la_valid = 0;
|
||||
while (!la_tb_valid) #`CP;
|
||||
$display(" -> wrote 0x0000 to state reg (addr 0x0000)");
|
||||
|
||||
// read
|
||||
tb_la_valid = 1;
|
||||
tb_la_rw = 0;
|
||||
#`CP
|
||||
tb_la_valid = 0;
|
||||
while (!la_tb_valid) #`CP;
|
||||
$display(" -> read 0x%h from state reg (addr 0x0000)", la_tb_rdata);
|
||||
|
||||
|
||||
#(10*`CP);
|
||||
/* ==== Test 2 End ==== */
|
||||
|
|
@ -135,7 +153,7 @@ module logic_analyzer_tb;
|
|||
tb_la_wdata = -16'sd69;
|
||||
#`CP
|
||||
tb_la_valid = 0;
|
||||
#`CP
|
||||
while (!la_tb_valid) #`CP;
|
||||
$display(" -> wrote -0d69 to trigger_loc reg (addr 0x0001)");
|
||||
|
||||
// read
|
||||
|
|
@ -146,6 +164,24 @@ module logic_analyzer_tb;
|
|||
while (!la_tb_valid) #`CP;
|
||||
$display(" -> read 0d%d from trigger_loc reg (addr 0x0001)", $signed(la_tb_rdata));
|
||||
|
||||
// write
|
||||
tb_la_addr = 1;
|
||||
tb_la_valid = 1;
|
||||
tb_la_rw = 1;
|
||||
tb_la_wdata = 0;
|
||||
#`CP
|
||||
tb_la_valid = 0;
|
||||
while (!la_tb_valid) #`CP;
|
||||
$display(" -> wrote 0x0000 to trigger_loc reg (addr 0x0001)");
|
||||
|
||||
// read
|
||||
tb_la_valid = 1;
|
||||
tb_la_rw = 0;
|
||||
#`CP
|
||||
tb_la_valid = 0;
|
||||
while (!la_tb_valid) #`CP;
|
||||
$display(" -> read 0x%h from trigger_loc reg (addr 0x0001)", $signed(la_tb_rdata));
|
||||
|
||||
|
||||
#(10*`CP);
|
||||
/* ==== Test 3 End ==== */
|
||||
|
|
@ -163,7 +199,7 @@ module logic_analyzer_tb;
|
|||
tb_la_wdata = 8;
|
||||
#`CP
|
||||
tb_la_valid = 0;
|
||||
#`CP
|
||||
while (!la_tb_valid) #`CP;
|
||||
$display(" -> wrote 0x0008 to larry_op reg (addr 0x0002)");
|
||||
|
||||
// read
|
||||
|
|
@ -191,7 +227,7 @@ module logic_analyzer_tb;
|
|||
tb_la_wdata = 1;
|
||||
#`CP
|
||||
tb_la_valid = 0;
|
||||
#`CP
|
||||
while (!la_tb_valid) #`CP;
|
||||
$display(" -> wrote 0x0001 to larry_arg reg (addr 0x0003)");
|
||||
|
||||
// read
|
||||
|
|
@ -212,18 +248,52 @@ module logic_analyzer_tb;
|
|||
$display("\n=== test 6: set larry = 1, verify core does not trigger ===");
|
||||
test_num = 6;
|
||||
|
||||
larry = 1;
|
||||
$display(" -> set larry = 1");
|
||||
larry = 1;
|
||||
|
||||
// read
|
||||
$display(" -> la core is in state 0x%h", la.state);
|
||||
$display(" -> la core is in state 0x%h", la.fsm.state);
|
||||
$display(" -> wait a clock cycle");
|
||||
#`CP
|
||||
$display(" -> la core is in state 0x%h", la.state);
|
||||
$display(" -> la core is in state 0x%h", la.fsm.state);
|
||||
$display(" -> set larry = 0");
|
||||
larry = 0;
|
||||
|
||||
|
||||
#(10*`CP);
|
||||
/* ==== Test 6 End ==== */
|
||||
|
||||
|
||||
|
||||
/* ==== Test 7 Begin ==== */
|
||||
$display("\n=== test 7: set larry = 1, verify core does trigger ===");
|
||||
test_num = 7;
|
||||
|
||||
// write
|
||||
tb_la_addr = 0;
|
||||
tb_la_valid = 1;
|
||||
tb_la_rw = 1;
|
||||
tb_la_wdata = 1;
|
||||
#`CP
|
||||
tb_la_valid = 0;
|
||||
#`CP
|
||||
$display(" -> wrote 0x0001 to state reg (addr 0x0000)");
|
||||
|
||||
#`CP
|
||||
|
||||
$display(" -> set larry = 1");
|
||||
larry = 1;
|
||||
|
||||
// read
|
||||
$display(" -> la core is in state 0x%h", la.fsm.state);
|
||||
$display(" -> wait a clock cycle");
|
||||
#`CP
|
||||
$display(" -> la core is in state 0x%h", la.fsm.state);
|
||||
|
||||
|
||||
#(200*`CP);
|
||||
/* ==== Test 7 End ==== */
|
||||
|
||||
$finish();
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
Loading…
Reference in New Issue