2016-02-26 19:08:40 -05:00
|
|
|
`include "etrace_regmap.vh"
|
2015-11-25 21:19:55 -05:00
|
|
|
module etrace (/*AUTOARG*/
|
|
|
|
// Outputs
|
2015-11-30 13:45:49 -05:00
|
|
|
data_access_out, data_packet_out, cfg_access_out, cfg_packet_out,
|
2015-11-25 21:19:55 -05:00
|
|
|
// Inputs
|
2015-11-30 13:45:49 -05:00
|
|
|
trace_clk, trace_trigger, trace_vector, cfg_access_in,
|
|
|
|
cfg_packet_in
|
2015-11-25 21:19:55 -05:00
|
|
|
);
|
|
|
|
|
|
|
|
parameter VW = 32; //width of vector to sample
|
|
|
|
parameter DW = 32; //width of counter
|
|
|
|
parameter AW = 32; //width of address input bus
|
|
|
|
parameter DEPTH = 1024; //memory depth
|
|
|
|
parameter ID = 999;
|
|
|
|
parameter NAME = "my";
|
|
|
|
parameter RFAW = 6; //
|
|
|
|
|
|
|
|
parameter MW = VW+DW; //memory width should be 64,128,256
|
|
|
|
parameter MAW = $clog2(DEPTH);//
|
|
|
|
parameter LSB = $clog2(MW/32);//address lsb for memory
|
|
|
|
|
2015-11-30 13:45:49 -05:00
|
|
|
//Logic analyzer interface
|
2015-11-25 21:19:55 -05:00
|
|
|
input trace_clk;
|
|
|
|
input trace_trigger;
|
|
|
|
input [VW-1:0] trace_vector;
|
2015-11-30 13:45:49 -05:00
|
|
|
|
|
|
|
//Data streaming interface
|
|
|
|
output data_access_out;
|
|
|
|
output [PW-1:0] data_packet_out;
|
|
|
|
|
|
|
|
//Config interface
|
|
|
|
input cfg_access_in;
|
|
|
|
input [PW-1:0] cfg_packet_in;
|
|
|
|
output cfg_access_out;
|
|
|
|
output [PW-1:0] cfg_packet_out;
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-11-25 21:19:55 -05:00
|
|
|
//local regs
|
|
|
|
reg [15:0] cfg_reg;
|
|
|
|
reg [DW-1:0] cycle_counter;
|
|
|
|
reg [VW-1:0] trace_vector_reg;
|
|
|
|
reg [2:0] mi_addr_reg;
|
|
|
|
reg [MAW-1:0] trace_addr;
|
|
|
|
|
|
|
|
wire mi_write;
|
|
|
|
wire mi_cfg_write;
|
|
|
|
wire [MW-1:0] mem_data;
|
|
|
|
wire trace_enable_sync;
|
|
|
|
|
2015-11-30 13:45:49 -05:00
|
|
|
|
|
|
|
wire [3:0] ctrlmode_out;
|
|
|
|
wire [DW-1:0] data_out;
|
|
|
|
wire [1:0] datamode_out;
|
|
|
|
wire [AW-1:0] dstaddr_out;
|
|
|
|
wire [AW-1:0] srcaddr_out;
|
|
|
|
wire write_out;
|
|
|
|
|
|
|
|
/*AUTOWIRE*/
|
|
|
|
// Beginning of automatic wires (for undeclared instantiated-module outputs)
|
|
|
|
wire [PW-1:0] packet_out; // From e2p of emesh2packet.v
|
|
|
|
// End of automatics
|
|
|
|
|
|
|
|
//###########################
|
|
|
|
//# PACKET PARSING
|
|
|
|
//###########################
|
|
|
|
|
|
|
|
//Config
|
|
|
|
packet2emesh p2e0 (/*AUTOINST*/
|
|
|
|
// Outputs
|
|
|
|
.write_out (write_out),
|
|
|
|
.datamode_out (datamode_out[1:0]),
|
|
|
|
.ctrlmode_out (ctrlmode_out[3:0]),
|
|
|
|
.data_out (data_out[DW-1:0]),
|
|
|
|
.dstaddr_out (dstaddr_out[AW-1:0]),
|
|
|
|
.srcaddr_out (srcaddr_out[AW-1:0]),
|
|
|
|
// Inputs
|
|
|
|
.packet_in (packet_in[PW-1:0]));
|
|
|
|
|
|
|
|
//Readback
|
|
|
|
emesh2packet e2p0 (/*AUTOINST*/
|
|
|
|
// Outputs
|
|
|
|
.packet_out (packet_out[PW-1:0]),
|
|
|
|
// Inputs
|
|
|
|
.write_in (write_in),
|
|
|
|
.datamode_in (datamode_in[1:0]),
|
|
|
|
.ctrlmode_in (ctrlmode_in[3:0]),
|
|
|
|
.dstaddr_in (dstaddr_in[AW-1:0]),
|
|
|
|
.data_in (data_in[DW-1:0]),
|
|
|
|
.srcaddr_in (srcaddr_in[AW-1:0]));
|
|
|
|
|
|
|
|
//Data
|
|
|
|
emesh2packet e2p0 (/*AUTOINST*/
|
|
|
|
// Outputs
|
|
|
|
.packet_out (packet_out[PW-1:0]),
|
|
|
|
// Inputs
|
|
|
|
.write_in (write_in),
|
|
|
|
.datamode_in (datamode_in[1:0]),
|
|
|
|
.ctrlmode_in (ctrlmode_in[3:0]),
|
|
|
|
.dstaddr_in (dstaddr_in[AW-1:0]),
|
|
|
|
.data_in (data_in[DW-1:0]),
|
|
|
|
.srcaddr_in (srcaddr_in[AW-1:0]));
|
|
|
|
|
2015-11-25 21:19:55 -05:00
|
|
|
|
|
|
|
|
|
|
|
//###########################
|
|
|
|
//# REGISTER INTERFACE
|
|
|
|
//###########################
|
|
|
|
|
|
|
|
assign mi_write = mi_en & mi_we;
|
|
|
|
assign mi_cfg_write = mi_write &
|
|
|
|
(mi_addr[31:20] ==ID) &
|
|
|
|
(mi_addr[19:16] ==`ETRACE_REGS) &
|
|
|
|
(mi_addr[RFAW+1:2]==`ETRACE_CFG);
|
|
|
|
|
|
|
|
assign mi_rd = mi_en &
|
|
|
|
(mi_addr[31:20] ==ID) &
|
|
|
|
(mi_addr[19:16] ==`ETRACE_MEM);
|
|
|
|
|
|
|
|
//TODO: parametrize
|
|
|
|
always @ (posedge mi_clk)
|
|
|
|
mi_addr_reg[2:0] <= mi_addr[2:0];
|
|
|
|
|
|
|
|
//TODO: parametrize, keep to 32 bits for now
|
|
|
|
assign mi_dout[DW-1:0] = mi_addr_reg[2] ? mem_data[63:32] :
|
|
|
|
mem_data[31:0];
|
|
|
|
|
|
|
|
//###########################
|
|
|
|
//# CONFIG
|
|
|
|
//###########################
|
2015-11-30 13:45:49 -05:00
|
|
|
//Destination start address ETRACE_BASEADDR [32 bit]
|
|
|
|
//Destination samples ETRACE_SAMPLES [32 bit]
|
|
|
|
|
2015-11-25 21:19:55 -05:00
|
|
|
always @ (posedge mi_clk)
|
|
|
|
if(!nreset)
|
|
|
|
cfg_reg[15:0] <= 'b0;
|
|
|
|
else if (mi_cfg_write)
|
|
|
|
cfg_reg[15:0] <= mi_din[15:0];
|
|
|
|
|
2015-11-30 13:45:49 -05:00
|
|
|
assign mi_trace_enable = cfg_reg[0];
|
|
|
|
assign mi_loop_enable = cfg_reg[1];//runs forever as circular buffer
|
|
|
|
assign mi_async_mode = cfg_reg[2];//treats input signals as async/sync
|
|
|
|
assign mi_samplerate = cfg_reg[7:4];
|
|
|
|
/*
|
|
|
|
* 100MS/s
|
|
|
|
* 50MS/s
|
|
|
|
* 25MS/s
|
|
|
|
* 12.5MS/s
|
|
|
|
* 6.25MS/s
|
|
|
|
* 3.125Ms/s
|
|
|
|
* 1.0Ms/s
|
|
|
|
* 0.5Ms/s
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
//###########################
|
|
|
|
//# "DMA"
|
|
|
|
//###########################
|
|
|
|
//With 64 channels + 32 bit timer (==96 bits)
|
|
|
|
//Max sample rate??
|
|
|
|
|
|
|
|
|
2015-11-25 21:19:55 -05:00
|
|
|
//################################
|
|
|
|
//# SYNC CFG SIGNALS TO SAMPLE CLK
|
|
|
|
//#################################
|
|
|
|
|
|
|
|
dsync #(.DW(1))
|
|
|
|
|
|
|
|
dsync(// Outputs
|
|
|
|
.dout (trace_enable),
|
|
|
|
// Inputs
|
|
|
|
.clk (trace_clk),
|
|
|
|
.din (mi_trace_enable)
|
|
|
|
);
|
|
|
|
|
|
|
|
//###########################
|
|
|
|
//# TIME KEEPER
|
|
|
|
//###########################
|
|
|
|
//count if trigger enabled and counter enabled (SW + HW)
|
|
|
|
|
|
|
|
always @ (posedge trace_clk)
|
|
|
|
if(~trace_enable)
|
|
|
|
cycle_counter[DW-1:0] <= 'b0;
|
|
|
|
else if (trace_trigger)
|
|
|
|
cycle_counter[DW-1:0] <= cycle_counter[DW-1:0] + 1'b1;
|
|
|
|
|
|
|
|
//###########################
|
|
|
|
//# SAMPLING LOGIC
|
|
|
|
//###########################
|
|
|
|
|
|
|
|
//Change detect logic
|
|
|
|
always @ (posedge trace_clk)
|
|
|
|
trace_vector_reg[VW-1:0] <= trace_vector[VW-1:0];
|
|
|
|
|
|
|
|
assign change_detect = |(trace_vector_reg[VW-1:0] ^ trace_vector[VW-1:0]);
|
|
|
|
|
|
|
|
//Sample signal
|
|
|
|
assign trace_sample = trace_enable &
|
|
|
|
trace_trigger &
|
|
|
|
change_detect;
|
|
|
|
|
|
|
|
//Address counter
|
|
|
|
always @ (posedge trace_clk)
|
|
|
|
if(~trace_enable)
|
|
|
|
trace_addr[MAW-1:0] <= 'b0;
|
|
|
|
else if (trace_sample)
|
|
|
|
trace_addr[MAW-1:0] <= trace_addr[MAW-1:0] + 1'b1;
|
2015-11-30 13:45:49 -05:00
|
|
|
|
|
|
|
//Trace memory
|
|
|
|
fifo_cdc fifo (// Outputs
|
|
|
|
.wait_out (),
|
|
|
|
.access_out (access_out),
|
|
|
|
.packet_out (packet_out[DW-1:0]),
|
|
|
|
// Inputs
|
|
|
|
.nreset (nreset),
|
|
|
|
.clk_in (clk_in),
|
|
|
|
.access_in (access_in),
|
|
|
|
.packet_in (packet_in[DW-1:0]),
|
|
|
|
.clk_out (clk_out),
|
|
|
|
.wait_in (wait_in));
|
|
|
|
|
2015-11-25 21:19:55 -05:00
|
|
|
`ifdef TARGET_SIM
|
|
|
|
reg [31:0] ftrace;
|
|
|
|
reg [255:0] tracefile;
|
|
|
|
initial
|
|
|
|
begin
|
|
|
|
$sformat(tracefile,"%s%s",NAME,".trace");
|
|
|
|
ftrace = $fopen({tracefile}, "w");
|
|
|
|
end
|
|
|
|
|
|
|
|
always @ (posedge trace_clk)
|
|
|
|
if(trace_sample)
|
|
|
|
$fwrite(ftrace, "%h,%0d\n",trace_vector[VW-1:0],cycle_counter[DW-1:0]);
|
|
|
|
|
|
|
|
`endif // `ifdef TARGET_SIM
|
|
|
|
|
|
|
|
endmodule // emailbox
|
|
|
|
|
|
|
|
|
|
|
|
// Local Variables:
|
|
|
|
// verilog-library-directories:("." "../../emesh/hdl" "../../memory/hdl" "../../common/hdl")
|
|
|
|
// End:
|