Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2d4a5af40a | ||
|
|
0526157bfc | ||
|
|
09e8ade74c | ||
|
|
8d8b409807 |
@@ -1,3 +0,0 @@
|
|||||||
[submodule "external/rtl_libs"]
|
|
||||||
path = external/rtl_libs
|
|
||||||
url = https://git.radiophotonics.ru/baulin.fa/rtl_libs.git
|
|
||||||
@@ -1,189 +0,0 @@
|
|||||||
// SPDX-License-Identifier: MIT
|
|
||||||
//
|
|
||||||
// SystemVerilog interface wrapper around alexforencich/verilog-axi axi_dma.v.
|
|
||||||
//
|
|
||||||
// AXI memory, AXI-Stream data, DMA descriptor, and DMA status channels are all
|
|
||||||
// exposed through compact interfaces. The original Forencich core remains
|
|
||||||
// untouched and is connected through local flat wires.
|
|
||||||
|
|
||||||
`default_nettype none
|
|
||||||
import dma_reg_pkg::*;
|
|
||||||
|
|
||||||
// DMA Specific wrappers & converters
|
|
||||||
module axi_dma_wrapper #(
|
|
||||||
parameter int unsigned AXI_DATA_WIDTH = 32,
|
|
||||||
|
|
||||||
parameter int unsigned AXI_STRB_WIDTH = AXI_DATA_WIDTH / 8,
|
|
||||||
parameter int unsigned AXI_ID_WIDTH = 8,
|
|
||||||
parameter int unsigned AXI_USER_WIDTH = 1,
|
|
||||||
parameter int unsigned AXI_MAX_BURST_LEN = 16,
|
|
||||||
|
|
||||||
parameter int unsigned AXIS_DATA_WIDTH = AXI_DATA_WIDTH,
|
|
||||||
parameter int unsigned AXIS_KEEP_ENABLE = AXIS_DATA_WIDTH > 8,
|
|
||||||
parameter int unsigned AXIS_KEEP_WIDTH = AXIS_DATA_WIDTH / 8,
|
|
||||||
parameter int unsigned AXIS_LAST_ENABLE = 1,
|
|
||||||
parameter int unsigned AXIS_ID_ENABLE = 1,
|
|
||||||
parameter int unsigned AXIS_DEST_ENABLE = 0,
|
|
||||||
parameter int unsigned AXIS_USER_ENABLE = 1,
|
|
||||||
|
|
||||||
parameter int unsigned ENABLE_SG = 0,
|
|
||||||
parameter int unsigned ENABLE_UNALIGNED = 0
|
|
||||||
)(
|
|
||||||
input logic clk,
|
|
||||||
input logic rst,
|
|
||||||
|
|
||||||
axis_if.slave s_axis_read_desc,
|
|
||||||
|
|
||||||
axis_if.master m_axis_read_desc_status,
|
|
||||||
|
|
||||||
axis_if.master m_axis_read_data,
|
|
||||||
|
|
||||||
axis_if.slave s_axis_write_desc,
|
|
||||||
|
|
||||||
axis_if.master m_axis_write_desc_status,
|
|
||||||
|
|
||||||
axis_if.slave s_axis_write_data,
|
|
||||||
|
|
||||||
axi4_if.master m_axi
|
|
||||||
);
|
|
||||||
|
|
||||||
dma_read_desc_t read_desc;
|
|
||||||
assign read_desc = dma_read_desc_t'(s_axis_read_desc.req.t.data);
|
|
||||||
|
|
||||||
|
|
||||||
dma_write_desc_t write_desc;
|
|
||||||
assign write_desc = dma_write_desc_t'(s_axis_write_desc.req.t.data);
|
|
||||||
|
|
||||||
|
|
||||||
dma_read_status_t read_status;
|
|
||||||
assign m_axis_read_desc_status.req.t.data = read_status;
|
|
||||||
logic m_axis_read_desc_status_valid;
|
|
||||||
assign m_axis_read_desc_status.req.t.valid = m_axis_read_desc_status_valid;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dma_write_status_t write_status;
|
|
||||||
assign m_axis_write_desc_status.req.t.data = write_status;
|
|
||||||
logic m_axis_write_desc_status_valid;
|
|
||||||
assign m_axis_write_desc_status.req.t.valid = m_axis_write_desc_status_valid;
|
|
||||||
|
|
||||||
|
|
||||||
// Original DMA: flat ports only.
|
|
||||||
axi_dma #(
|
|
||||||
.AXI_DATA_WIDTH (AXI_DATA_WIDTH),
|
|
||||||
.AXI_ADDR_WIDTH (dma_reg_pkg::AXI_ADDR_WIDTH),
|
|
||||||
.AXI_STRB_WIDTH (AXI_STRB_WIDTH),
|
|
||||||
.AXI_ID_WIDTH (AXI_ID_WIDTH),
|
|
||||||
.AXI_MAX_BURST_LEN (AXI_MAX_BURST_LEN),
|
|
||||||
.AXIS_DATA_WIDTH (AXIS_DATA_WIDTH),
|
|
||||||
.AXIS_KEEP_ENABLE (AXIS_KEEP_ENABLE),
|
|
||||||
.AXIS_KEEP_WIDTH (AXIS_KEEP_WIDTH),
|
|
||||||
.AXIS_LAST_ENABLE (AXIS_LAST_ENABLE),
|
|
||||||
.AXIS_ID_ENABLE (AXIS_ID_ENABLE),
|
|
||||||
.AXIS_ID_WIDTH (dma_reg_pkg::AXIS_ID_WIDTH),
|
|
||||||
.AXIS_DEST_ENABLE (AXIS_DEST_ENABLE),
|
|
||||||
.AXIS_DEST_WIDTH (dma_reg_pkg::AXIS_DEST_WIDTH),
|
|
||||||
.AXIS_USER_ENABLE (AXIS_USER_ENABLE),
|
|
||||||
.AXIS_USER_WIDTH (dma_reg_pkg::AXIS_USER_WIDTH),
|
|
||||||
.LEN_WIDTH (dma_reg_pkg::LEN_WIDTH),
|
|
||||||
.TAG_WIDTH (dma_reg_pkg::TAG_WIDTH),
|
|
||||||
.ENABLE_SG (ENABLE_SG),
|
|
||||||
.ENABLE_UNALIGNED (ENABLE_UNALIGNED)
|
|
||||||
) i_axi_dma (
|
|
||||||
.clk (clk),
|
|
||||||
.rst (rst),
|
|
||||||
|
|
||||||
.s_axis_read_desc_addr (read_desc.addr),
|
|
||||||
.s_axis_read_desc_len (read_desc.len),
|
|
||||||
.s_axis_read_desc_tag (read_desc.tag),
|
|
||||||
.s_axis_read_desc_id (read_desc.id),
|
|
||||||
.s_axis_read_desc_dest (read_desc.dest),
|
|
||||||
.s_axis_read_desc_user (read_desc.user),
|
|
||||||
.s_axis_read_desc_valid (s_axis_read_desc.req.t.valid),
|
|
||||||
.s_axis_read_desc_ready (s_axis_read_desc.resp.ready),
|
|
||||||
|
|
||||||
.m_axis_read_desc_status_tag (read_status.tag),
|
|
||||||
.m_axis_read_desc_status_error (read_status.error),
|
|
||||||
.m_axis_read_desc_status_valid (m_axis_read_desc_status_valid),
|
|
||||||
|
|
||||||
.m_axis_read_data_tdata (m_axis_read_data.req.t.data),
|
|
||||||
.m_axis_read_data_tkeep (m_axis_read_data.req.t.keep),
|
|
||||||
.m_axis_read_data_tvalid (m_axis_read_data.req.t.valid),
|
|
||||||
.m_axis_read_data_tready (m_axis_read_data.resp.ready),
|
|
||||||
.m_axis_read_data_tlast (m_axis_read_data.req.t.last),
|
|
||||||
.m_axis_read_data_tid (m_axis_read_data.req.t.id),
|
|
||||||
.m_axis_read_data_tdest (m_axis_read_data.req.t.dest),
|
|
||||||
.m_axis_read_data_tuser (m_axis_read_data.req.t.user),
|
|
||||||
|
|
||||||
.s_axis_write_desc_addr (write_desc.addr),
|
|
||||||
.s_axis_write_desc_len (write_desc.len),
|
|
||||||
.s_axis_write_desc_tag (write_desc.tag),
|
|
||||||
.s_axis_write_desc_valid (s_axis_write_desc.req.t.valid),
|
|
||||||
.s_axis_write_desc_ready (s_axis_write_desc.resp.ready),
|
|
||||||
|
|
||||||
.m_axis_write_desc_status_len (write_status.len),
|
|
||||||
.m_axis_write_desc_status_tag (write_status.tag),
|
|
||||||
.m_axis_write_desc_status_id (write_status.id),
|
|
||||||
.m_axis_write_desc_status_dest (write_status.dest),
|
|
||||||
.m_axis_write_desc_status_user (write_status.user),
|
|
||||||
.m_axis_write_desc_status_error (write_status.error),
|
|
||||||
.m_axis_write_desc_status_valid (m_axis_write_desc_status_valid),
|
|
||||||
|
|
||||||
.s_axis_write_data_tdata (s_axis_write_data.req.t.data),
|
|
||||||
.s_axis_write_data_tkeep (s_axis_write_data.req.t.keep),
|
|
||||||
.s_axis_write_data_tvalid (s_axis_write_data.req.t.valid),
|
|
||||||
.s_axis_write_data_tready (s_axis_write_data.resp.ready),
|
|
||||||
.s_axis_write_data_tlast (s_axis_write_data.req.t.last),
|
|
||||||
.s_axis_write_data_tid (s_axis_write_data.req.t.id),
|
|
||||||
.s_axis_write_data_tdest (s_axis_write_data.req.t.dest),
|
|
||||||
.s_axis_write_data_tuser (s_axis_write_data.req.t.user),
|
|
||||||
|
|
||||||
.m_axi_awid (m_axi.req.aw.id),
|
|
||||||
.m_axi_awaddr (m_axi.req.aw.addr),
|
|
||||||
.m_axi_awlen (m_axi.req.aw.len),
|
|
||||||
.m_axi_awsize (m_axi.req.aw.size),
|
|
||||||
.m_axi_awburst (m_axi.req.aw.burst),
|
|
||||||
.m_axi_awlock (m_axi.req.aw.lock),
|
|
||||||
.m_axi_awcache (m_axi.req.aw.cache),
|
|
||||||
.m_axi_awprot (m_axi.req.aw.prot),
|
|
||||||
.m_axi_awvalid (m_axi.req.aw.valid),
|
|
||||||
.m_axi_awready (m_axi.resp.aw_ready),
|
|
||||||
|
|
||||||
.m_axi_wdata (m_axi.req.w.data),
|
|
||||||
.m_axi_wstrb (m_axi.req.w.strb),
|
|
||||||
.m_axi_wlast ( m_axi.req.w.last),
|
|
||||||
.m_axi_wvalid (m_axi.req.w.valid),
|
|
||||||
.m_axi_wready (m_axi.resp.w_ready),
|
|
||||||
|
|
||||||
.m_axi_bid (m_axi.resp.b.id),
|
|
||||||
.m_axi_bresp (m_axi.resp.b.resp),
|
|
||||||
.m_axi_bvalid (m_axi.resp.b.valid),
|
|
||||||
.m_axi_bready (m_axi.req.b_ready),
|
|
||||||
|
|
||||||
.m_axi_arid (m_axi.req.ar.id),
|
|
||||||
.m_axi_araddr (m_axi.req.ar.addr),
|
|
||||||
.m_axi_arlen (m_axi.req.ar.len),
|
|
||||||
.m_axi_arsize (m_axi.req.ar.size),
|
|
||||||
.m_axi_arburst (m_axi.req.ar.burst),
|
|
||||||
.m_axi_arlock (m_axi.req.ar.lock),
|
|
||||||
.m_axi_arcache (m_axi.req.ar.cache),
|
|
||||||
.m_axi_arprot (m_axi.req.ar.prot),
|
|
||||||
.m_axi_arvalid (m_axi.req.ar.valid),
|
|
||||||
.m_axi_arready (m_axi.resp.ar_ready),
|
|
||||||
|
|
||||||
.m_axi_rid (m_axi.resp.r.id),
|
|
||||||
.m_axi_rdata (m_axi.resp.r.data),
|
|
||||||
.m_axi_rresp (m_axi.resp.r.resp),
|
|
||||||
.m_axi_rlast (m_axi.resp.r.last),
|
|
||||||
.m_axi_rvalid (m_axi.resp.r.valid),
|
|
||||||
.m_axi_rready (m_axi.req.r_ready),
|
|
||||||
|
|
||||||
.read_enable (1'b1),
|
|
||||||
.write_enable (1'b1),
|
|
||||||
.write_abort (1'b0)
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
endmodule : axi_dma_wrapper
|
|
||||||
|
|
||||||
`default_nettype wire
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
module axi_ram_wrapper
|
|
||||||
#(
|
|
||||||
parameter int unsigned DATA_WIDTH = 32,
|
|
||||||
parameter int unsigned ADDR_WIDTH = 16,
|
|
||||||
parameter int unsigned ID_WIDTH = 8,
|
|
||||||
parameter int unsigned PIPELINE_OUTPUT = 0
|
|
||||||
)
|
|
||||||
(
|
|
||||||
input logic clk,
|
|
||||||
input logic rst,
|
|
||||||
axi4_if.slave s_axi
|
|
||||||
);
|
|
||||||
|
|
||||||
axi_ram
|
|
||||||
#(
|
|
||||||
.DATA_WIDTH(DATA_WIDTH),
|
|
||||||
.ADDR_WIDTH(ADDR_WIDTH),
|
|
||||||
.ID_WIDTH(ID_WIDTH),
|
|
||||||
.PIPELINE_OUTPUT(PIPELINE_OUTPUT)
|
|
||||||
) axi_ram_inst
|
|
||||||
(
|
|
||||||
.clk(clk),
|
|
||||||
.rst(rst),
|
|
||||||
.s_axi_awid(s_axi.req.aw.id),
|
|
||||||
.s_axi_awaddr(s_axi.req.aw.addr),
|
|
||||||
.s_axi_awlen(s_axi.req.aw.len),
|
|
||||||
.s_axi_awsize(s_axi.req.aw.size),
|
|
||||||
.s_axi_awburst(s_axi.req.aw.burst),
|
|
||||||
.s_axi_awlock(s_axi.req.aw.lock),
|
|
||||||
.s_axi_awcache(s_axi.req.aw.cache),
|
|
||||||
.s_axi_awprot(s_axi.req.aw.prot),
|
|
||||||
.s_axi_awvalid(s_axi.req.aw.valid),
|
|
||||||
.s_axi_awready(s_axi.resp.aw_ready),
|
|
||||||
.s_axi_wdata(s_axi.req.w.data),
|
|
||||||
.s_axi_wstrb(s_axi.req.w.strb),
|
|
||||||
.s_axi_wlast(s_axi.req.w.last),
|
|
||||||
.s_axi_wvalid(s_axi.req.w.valid),
|
|
||||||
.s_axi_wready(s_axi.resp.w_ready),
|
|
||||||
.s_axi_bid(s_axi.resp.b.id),
|
|
||||||
.s_axi_bresp(s_axi.resp.b.resp),
|
|
||||||
.s_axi_bvalid(s_axi.resp.b.valid),
|
|
||||||
.s_axi_bready(s_axi.req.b_ready),
|
|
||||||
.s_axi_arid(s_axi.req.ar.id),
|
|
||||||
.s_axi_araddr(s_axi.req.ar.addr),
|
|
||||||
.s_axi_arlen(s_axi.req.ar.len),
|
|
||||||
.s_axi_arsize(s_axi.req.ar.size),
|
|
||||||
.s_axi_arburst(s_axi.req.ar.burst),
|
|
||||||
.s_axi_arlock(s_axi.req.ar.lock),
|
|
||||||
.s_axi_arcache(s_axi.req.ar.cache),
|
|
||||||
.s_axi_arprot(s_axi.req.ar.prot),
|
|
||||||
.s_axi_arvalid(s_axi.req.ar.valid),
|
|
||||||
.s_axi_arready(s_axi.resp.ar_ready),
|
|
||||||
.s_axi_rid(s_axi.resp.r.id),
|
|
||||||
.s_axi_rdata(s_axi.resp.r.data),
|
|
||||||
.s_axi_rresp(s_axi.resp.r.resp),
|
|
||||||
.s_axi_rlast(s_axi.resp.r.last),
|
|
||||||
.s_axi_rvalid(s_axi.resp.r.valid),
|
|
||||||
.s_axi_rready(s_axi.req.r_ready)
|
|
||||||
);
|
|
||||||
endmodule
|
|
||||||
@@ -1,193 +0,0 @@
|
|||||||
import dma_reg_pkg::*;
|
|
||||||
|
|
||||||
module wrapper_controller_dma
|
|
||||||
#(
|
|
||||||
parameter int unsigned ADDR_W = 16,
|
|
||||||
parameter int unsigned DATA_W = 32,
|
|
||||||
parameter int unsigned USER_W = 1,
|
|
||||||
|
|
||||||
parameter int unsigned DAC_DATA_WIDTH = 12,
|
|
||||||
|
|
||||||
parameter int unsigned AXI_DATA_WIDTH = 32,
|
|
||||||
|
|
||||||
parameter int unsigned AXI_STRB_WIDTH = AXI_DATA_WIDTH / 8,
|
|
||||||
parameter int unsigned AXI_ID_WIDTH = 8,
|
|
||||||
parameter int unsigned AXI_USER_WIDTH = 1,
|
|
||||||
parameter int unsigned AXI_MAX_BURST_LEN = 16,
|
|
||||||
|
|
||||||
parameter int unsigned AXIS_DATA_WIDTH = AXI_DATA_WIDTH,
|
|
||||||
parameter int unsigned AXIS_KEEP_ENABLE = AXIS_DATA_WIDTH > 8,
|
|
||||||
parameter int unsigned AXIS_KEEP_WIDTH = AXIS_DATA_WIDTH / 8,
|
|
||||||
parameter int unsigned AXIS_LAST_ENABLE = 1,
|
|
||||||
parameter int unsigned AXIS_ID_ENABLE = 1,
|
|
||||||
parameter int unsigned AXIS_DEST_ENABLE = 0,
|
|
||||||
parameter int unsigned AXIS_USER_ENABLE = 1,
|
|
||||||
|
|
||||||
parameter int unsigned ENABLE_SG = 0,
|
|
||||||
parameter int unsigned ENABLE_UNALIGNED = 0,
|
|
||||||
|
|
||||||
parameter int unsigned PIPELINE_OUTPUT = 0
|
|
||||||
)
|
|
||||||
(
|
|
||||||
input logic ctrl_clk,
|
|
||||||
input logic dac_clk_in,
|
|
||||||
input logic adc_clk_in,
|
|
||||||
input logic rst_n,
|
|
||||||
axi4l_if.slave s_axil,
|
|
||||||
|
|
||||||
// adc_clk_in domain
|
|
||||||
input logic finish,
|
|
||||||
output logic [31:0] adc_window_size,
|
|
||||||
|
|
||||||
// dac_clk_in domain outputs
|
|
||||||
output logic [31:0] dac_pulse_width,
|
|
||||||
output logic [31:0] dac_pulse_period,
|
|
||||||
output logic [DAC_DATA_WIDTH-1:0] dac_pulse_height,
|
|
||||||
output logic [15:0] dac_pulse_num,
|
|
||||||
|
|
||||||
// adc_clk_in domain outputs
|
|
||||||
output logic [31:0] adc_pulse_period,
|
|
||||||
output logic [15:0] adc_pulse_num,
|
|
||||||
|
|
||||||
// pulse outputs
|
|
||||||
output logic dac_start,
|
|
||||||
output logic adc_start,
|
|
||||||
output logic dac_rst,
|
|
||||||
output logic adc_rst,
|
|
||||||
|
|
||||||
axis_if.master m_axis_read_data,
|
|
||||||
axis_if.slave s_axis_write_data
|
|
||||||
);
|
|
||||||
|
|
||||||
axis_if #(
|
|
||||||
.DATA_W($bits(dma_read_status_t)),
|
|
||||||
.KEEP_W(($bits(dma_read_status_t)+7)/8),
|
|
||||||
.ID_W(dma_reg_pkg::AXIS_ID_WIDTH),
|
|
||||||
.DEST_W(dma_reg_pkg::AXIS_DEST_WIDTH),
|
|
||||||
.USER_W(dma_reg_pkg::AXIS_USER_WIDTH)
|
|
||||||
) s_axis_status_read (
|
|
||||||
.aclk(ctrl_clk),
|
|
||||||
.aresetn(rst_n)
|
|
||||||
);
|
|
||||||
|
|
||||||
axis_if #(
|
|
||||||
.DATA_W($bits(dma_write_status_t)),
|
|
||||||
.KEEP_W(($bits(dma_write_status_t)+7)/8),
|
|
||||||
.ID_W(dma_reg_pkg::AXIS_ID_WIDTH),
|
|
||||||
.DEST_W(dma_reg_pkg::AXIS_DEST_WIDTH),
|
|
||||||
.USER_W(dma_reg_pkg::AXIS_USER_WIDTH)
|
|
||||||
) s_axis_status_write (
|
|
||||||
.aclk(ctrl_clk),
|
|
||||||
.aresetn(rst_n)
|
|
||||||
);
|
|
||||||
|
|
||||||
axis_if #(
|
|
||||||
.DATA_W($bits(dma_read_desc_t)),
|
|
||||||
.KEEP_W(($bits(dma_read_desc_t)+7)/8),
|
|
||||||
.ID_W(dma_reg_pkg::AXIS_ID_WIDTH),
|
|
||||||
.DEST_W(dma_reg_pkg::AXIS_DEST_WIDTH),
|
|
||||||
.USER_W(dma_reg_pkg::AXIS_USER_WIDTH)
|
|
||||||
) m_axis_desc_read (
|
|
||||||
.aclk(ctrl_clk),
|
|
||||||
.aresetn(rst_n)
|
|
||||||
);
|
|
||||||
|
|
||||||
axis_if #(
|
|
||||||
.DATA_W($bits(dma_write_desc_t)),
|
|
||||||
.KEEP_W(($bits(dma_write_desc_t)+7)/8),
|
|
||||||
.ID_W(dma_reg_pkg::AXIS_ID_WIDTH),
|
|
||||||
.DEST_W(dma_reg_pkg::AXIS_DEST_WIDTH),
|
|
||||||
.USER_W(dma_reg_pkg::AXIS_USER_WIDTH)
|
|
||||||
) m_axis_desc_write (
|
|
||||||
.aclk(ctrl_clk),
|
|
||||||
.aresetn(rst_n)
|
|
||||||
);
|
|
||||||
|
|
||||||
controller_wrapper_axil
|
|
||||||
#(
|
|
||||||
.ADDR_W(ADDR_W),
|
|
||||||
.DATA_W(DATA_W),
|
|
||||||
.USER_W(USER_W),
|
|
||||||
.DAC_DATA_WIDTH(DAC_DATA_WIDTH)
|
|
||||||
)
|
|
||||||
controller_wrapper_axil_inst
|
|
||||||
(
|
|
||||||
.ctrl_clk(ctrl_clk),
|
|
||||||
.dac_clk_in(dac_clk_in),
|
|
||||||
.adc_clk_in(adc_clk_in),
|
|
||||||
.rst_n(rst_n),
|
|
||||||
|
|
||||||
.s_axil(s_axil),
|
|
||||||
|
|
||||||
.finish(finish),
|
|
||||||
.adc_window_size(adc_window_size),
|
|
||||||
.dac_pulse_width(dac_pulse_width),
|
|
||||||
.dac_pulse_period(dac_pulse_period),
|
|
||||||
.dac_pulse_height(dac_pulse_height),
|
|
||||||
.dac_pulse_num(dac_pulse_num),
|
|
||||||
.adc_pulse_period(adc_pulse_period),
|
|
||||||
.adc_pulse_num(adc_pulse_num),
|
|
||||||
.dac_start(dac_start),
|
|
||||||
.adc_start(adc_start),
|
|
||||||
.dac_rst(dac_rst),
|
|
||||||
.adc_rst(adc_rst),
|
|
||||||
|
|
||||||
.s_axis_status_read(s_axis_status_read),
|
|
||||||
.s_axis_status_write(s_axis_status_write),
|
|
||||||
.m_axis_desc_read(m_axis_desc_read),
|
|
||||||
.m_axis_desc_write(m_axis_desc_write)
|
|
||||||
);
|
|
||||||
|
|
||||||
axi4_if #(
|
|
||||||
.ADDR_W(dma_reg_pkg::AXI_ADDR_WIDTH),
|
|
||||||
.DATA_W(AXI_DATA_WIDTH),
|
|
||||||
.ID_W (AXI_ID_WIDTH),
|
|
||||||
.USER_W(AXI_USER_WIDTH)
|
|
||||||
) m_axi (
|
|
||||||
.aclk(ctrl_clk),
|
|
||||||
.aresetn(rst_n)
|
|
||||||
);
|
|
||||||
|
|
||||||
axi_dma_wrapper
|
|
||||||
#(
|
|
||||||
.AXI_DATA_WIDTH(AXI_DATA_WIDTH),
|
|
||||||
.AXI_STRB_WIDTH(AXI_STRB_WIDTH),
|
|
||||||
.AXI_USER_WIDTH(AXI_USER_WIDTH),
|
|
||||||
.AXI_MAX_BURST_LEN(AXI_MAX_BURST_LEN),
|
|
||||||
.AXIS_DATA_WIDTH(AXIS_DATA_WIDTH),
|
|
||||||
.AXIS_KEEP_ENABLE(AXIS_KEEP_ENABLE),
|
|
||||||
.AXIS_KEEP_WIDTH(AXIS_KEEP_WIDTH),
|
|
||||||
.AXIS_LAST_ENABLE(AXIS_LAST_ENABLE),
|
|
||||||
.AXIS_ID_ENABLE(AXIS_ID_ENABLE),
|
|
||||||
.AXIS_DEST_ENABLE(AXIS_DEST_ENABLE),
|
|
||||||
.AXIS_USER_ENABLE(AXIS_USER_ENABLE),
|
|
||||||
.ENABLE_SG(ENABLE_SG),
|
|
||||||
.ENABLE_UNALIGNED(ENABLE_UNALIGNED)
|
|
||||||
)
|
|
||||||
axi_dma_wrapper_inst
|
|
||||||
(
|
|
||||||
.clk(ctrl_clk),
|
|
||||||
.rst(!rst_n),
|
|
||||||
.s_axis_read_desc(m_axis_desc_read),
|
|
||||||
.m_axis_read_desc_status(s_axis_status_read),
|
|
||||||
.m_axis_read_data(m_axis_read_data),
|
|
||||||
.s_axis_write_desc(m_axis_desc_write),
|
|
||||||
.m_axis_write_desc_status(s_axis_status_write),
|
|
||||||
.s_axis_write_data(s_axis_write_data),
|
|
||||||
.m_axi(m_axi)
|
|
||||||
);
|
|
||||||
|
|
||||||
axi_ram_wrapper
|
|
||||||
#(
|
|
||||||
.DATA_WIDTH(AXI_DATA_WIDTH),
|
|
||||||
.ADDR_WIDTH(dma_reg_pkg::AXI_ADDR_WIDTH),
|
|
||||||
.ID_WIDTH(dma_reg_pkg::AXIS_ID_WIDTH),
|
|
||||||
.PIPELINE_OUTPUT(PIPELINE_OUTPUT)
|
|
||||||
) axi_ram_wrapper_inst
|
|
||||||
(
|
|
||||||
.clk(ctrl_clk),
|
|
||||||
.rst(!rst_n),
|
|
||||||
.s_axi(m_axi)
|
|
||||||
);
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
TOPLEVEL_LANG = verilog
|
|
||||||
SIM ?= verilator
|
|
||||||
|
|
||||||
PWD := $(shell pwd)
|
|
||||||
|
|
||||||
WRAP_DIR = $(PWD)/../src
|
|
||||||
RTL_DIR = $(PWD)/../../controller/src
|
|
||||||
LIBS_DIR = $(PWD)/../../../external/rtl_libs
|
|
||||||
|
|
||||||
VERILOG_SOURCES += $(LIBS_DIR)/axi/rtl/axi_pkg.sv
|
|
||||||
VERILOG_SOURCES += $(RTL_DIR)/dma_reg_pkg.sv
|
|
||||||
VERILOG_SOURCES += $(LIBS_DIR)/axi/rtl/axi_if.sv
|
|
||||||
VERILOG_SOURCES += $(LIBS_DIR)/axi/axi_reg/axi4l_reg_map.sv
|
|
||||||
VERILOG_SOURCES += $(LIBS_DIR)/external/verilog-axi/rtl/axi_dma_rd.v
|
|
||||||
VERILOG_SOURCES += $(LIBS_DIR)/external/verilog-axi/rtl/axi_dma_wr.v
|
|
||||||
VERILOG_SOURCES += $(LIBS_DIR)/external/verilog-axi/rtl/axi_dma.v
|
|
||||||
VERILOG_SOURCES += $(LIBS_DIR)/external/verilog-axi/rtl/axi_ram.v
|
|
||||||
VERILOG_SOURCES += $(RTL_DIR)/axi_ram_wrapper.sv
|
|
||||||
VERILOG_SOURCES += $(RTL_DIR)/controller.sv
|
|
||||||
VERILOG_SOURCES += $(RTL_DIR)/dma_controller.sv
|
|
||||||
VERILOG_SOURCES += $(RTL_DIR)/shaper_axis_desc.sv
|
|
||||||
VERILOG_SOURCES += $(RTL_DIR)/shaper_axis_status.sv
|
|
||||||
VERILOG_SOURCES += $(RTL_DIR)/controller_wrapper_axil.sv
|
|
||||||
VERILOG_SOURCES += $(RTL_DIR)/axi4l_reg_map_controller_pkg.sv
|
|
||||||
VERILOG_SOURCES += $(RTL_DIR)/axis_defaults_helper.sv
|
|
||||||
VERILOG_SOURCES += $(RTL_DIR)/axi4l_reg_map_controller.sv
|
|
||||||
VERILOG_SOURCES += $(WRAP_DIR)/wrapper_controller_dma.sv
|
|
||||||
VERILOG_SOURCES += $(WRAP_DIR)/axi_dma_wrapper_if.sv
|
|
||||||
VERILOG_SOURCES += $(PWD)/tb_controller_dma_wrapper_axil.sv
|
|
||||||
|
|
||||||
TOPLEVEL = tb_controller_dma_wrapper_axil
|
|
||||||
MODULE = test_controller_and_dma
|
|
||||||
|
|
||||||
|
|
||||||
ifeq ($(SIM),verilator)
|
|
||||||
EXTRA_ARGS += --trace --trace-structs
|
|
||||||
EXTRA_ARGS += -I$(LIBS_DIR)/axi/rtl/
|
|
||||||
COMPILE_ARGS += -Wno-fatal
|
|
||||||
COMPILE_ARGS += -I$(LIBS_DIR)/axi/rtl/
|
|
||||||
EXTRA_ARGS += --trace
|
|
||||||
EXTRA_ARGS += --trace-structs
|
|
||||||
EXTRA_ARGS += --public-flat-rw
|
|
||||||
EXTRA_ARGS += -Wno-fatal
|
|
||||||
EXTRA_ARGS += --timing
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
include $(shell cocotb-config --makefiles)/Makefile.sim
|
|
||||||
@@ -1,298 +0,0 @@
|
|||||||
|
|
||||||
import dma_reg_pkg::*;
|
|
||||||
|
|
||||||
module tb_controller_wrapper_axil #(
|
|
||||||
parameter int unsigned ADDR_W = 16,
|
|
||||||
parameter int unsigned DATA_W = 32,
|
|
||||||
parameter int unsigned USER_W = 1,
|
|
||||||
|
|
||||||
parameter int unsigned DAC_DATA_WIDTH = 12,
|
|
||||||
|
|
||||||
parameter int unsigned AXI_DATA_WIDTH = 32,
|
|
||||||
|
|
||||||
parameter int unsigned AXI_STRB_WIDTH = AXI_DATA_WIDTH / 8,
|
|
||||||
parameter int unsigned AXI_ID_WIDTH = 8,
|
|
||||||
parameter int unsigned AXI_USER_WIDTH = 1,
|
|
||||||
parameter int unsigned AXI_MAX_BURST_LEN = 16,
|
|
||||||
|
|
||||||
parameter int unsigned AXIS_DATA_WIDTH = AXI_DATA_WIDTH,
|
|
||||||
parameter int unsigned AXIS_KEEP_ENABLE = AXIS_DATA_WIDTH > 8,
|
|
||||||
parameter int unsigned AXIS_KEEP_WIDTH = AXIS_DATA_WIDTH / 8,
|
|
||||||
parameter int unsigned AXIS_LAST_ENABLE = 1,
|
|
||||||
parameter int unsigned AXIS_ID_ENABLE = 1,
|
|
||||||
parameter int unsigned AXIS_DEST_ENABLE = 0,
|
|
||||||
parameter int unsigned AXIS_USER_ENABLE = 1,
|
|
||||||
|
|
||||||
parameter int unsigned ENABLE_SG = 0,
|
|
||||||
parameter int unsigned ENABLE_UNALIGNED = 0
|
|
||||||
)(
|
|
||||||
input logic ctrl_clk,
|
|
||||||
input logic rst,
|
|
||||||
|
|
||||||
input logic [ADDR_W-1:0] s_axil_awaddr,
|
|
||||||
input logic [2:0] s_axil_awprot,
|
|
||||||
input logic s_axil_awvalid,
|
|
||||||
output logic s_axil_awready,
|
|
||||||
|
|
||||||
input logic [DATA_W-1:0] s_axil_wdata,
|
|
||||||
input logic [DATA_W/8-1:0] s_axil_wstrb,
|
|
||||||
input logic s_axil_wvalid,
|
|
||||||
output logic s_axil_wready,
|
|
||||||
|
|
||||||
output logic [1:0] s_axil_bresp,
|
|
||||||
output logic s_axil_bvalid,
|
|
||||||
input logic s_axil_bready,
|
|
||||||
|
|
||||||
input logic [ADDR_W-1:0] s_axil_araddr,
|
|
||||||
input logic [2:0] s_axil_arprot,
|
|
||||||
input logic s_axil_arvalid,
|
|
||||||
output logic s_axil_arready,
|
|
||||||
|
|
||||||
output logic [DATA_W-1:0] s_axil_rdata,
|
|
||||||
output logic [1:0] s_axil_rresp,
|
|
||||||
output logic s_axil_rvalid,
|
|
||||||
input logic s_axil_rready,
|
|
||||||
|
|
||||||
input wire [AXIS_DATA_WIDTH-1:0] s_axis_write_data_tdata,
|
|
||||||
input wire [AXIS_KEEP_WIDTH-1:0] s_axis_write_data_tkeep,
|
|
||||||
input wire s_axis_write_data_tvalid,
|
|
||||||
output wire s_axis_write_data_tready,
|
|
||||||
input wire s_axis_write_data_tlast,
|
|
||||||
input wire [AXIS_ID_WIDTH-1:0] s_axis_write_data_tid,
|
|
||||||
input wire [AXIS_DEST_WIDTH-1:0] s_axis_write_data_tdest,
|
|
||||||
input wire [AXIS_USER_WIDTH-1:0] s_axis_write_data_tuser,
|
|
||||||
|
|
||||||
output wire [AXIS_DATA_WIDTH-1:0] m_axis_read_data_tdata,
|
|
||||||
output wire [AXIS_KEEP_WIDTH-1:0] m_axis_read_data_tkeep,
|
|
||||||
output wire m_axis_read_data_tvalid,
|
|
||||||
input wire m_axis_read_data_tready,
|
|
||||||
output wire m_axis_read_data_tlast,
|
|
||||||
output wire [AXIS_ID_WIDTH-1:0] m_axis_read_data_tid,
|
|
||||||
output wire [AXIS_DEST_WIDTH-1:0] m_axis_read_data_tdest,
|
|
||||||
output wire [AXIS_USER_WIDTH-1:0] m_axis_read_data_tuser,
|
|
||||||
|
|
||||||
output wire [AXI_ID_WIDTH-1:0] m_axi_awid,
|
|
||||||
output wire [AXI_ADDR_WIDTH-1:0] m_axi_awaddr,
|
|
||||||
output wire [7:0] m_axi_awlen,
|
|
||||||
output wire [2:0] m_axi_awsize,
|
|
||||||
output wire [1:0] m_axi_awburst,
|
|
||||||
output wire m_axi_awlock,
|
|
||||||
output wire [3:0] m_axi_awcache,
|
|
||||||
output wire [2:0] m_axi_awprot,
|
|
||||||
output wire m_axi_awvalid,
|
|
||||||
input wire m_axi_awready,
|
|
||||||
output wire [AXI_DATA_WIDTH-1:0] m_axi_wdata,
|
|
||||||
output wire [AXI_STRB_WIDTH-1:0] m_axi_wstrb,
|
|
||||||
output wire m_axi_wlast,
|
|
||||||
output wire m_axi_wvalid,
|
|
||||||
input wire m_axi_wready,
|
|
||||||
input wire [AXI_ID_WIDTH-1:0] m_axi_bid,
|
|
||||||
input wire [1:0] m_axi_bresp,
|
|
||||||
input wire m_axi_bvalid,
|
|
||||||
output wire m_axi_bready,
|
|
||||||
output wire [AXI_ID_WIDTH-1:0] m_axi_arid,
|
|
||||||
output wire [AXI_ADDR_WIDTH-1:0] m_axi_araddr,
|
|
||||||
output wire [7:0] m_axi_arlen,
|
|
||||||
output wire [2:0] m_axi_arsize,
|
|
||||||
output wire [1:0] m_axi_arburst,
|
|
||||||
output wire m_axi_arlock,
|
|
||||||
output wire [3:0] m_axi_arcache,
|
|
||||||
output wire [2:0] m_axi_arprot,
|
|
||||||
output wire m_axi_arvalid,
|
|
||||||
input wire m_axi_arready,
|
|
||||||
input wire [AXI_ID_WIDTH-1:0] m_axi_rid,
|
|
||||||
input wire [AXI_DATA_WIDTH-1:0] m_axi_rdata,
|
|
||||||
input wire [1:0] m_axi_rresp,
|
|
||||||
input wire m_axi_rlast,
|
|
||||||
input wire m_axi_rvalid,
|
|
||||||
output wire m_axi_rready
|
|
||||||
|
|
||||||
|
|
||||||
);
|
|
||||||
|
|
||||||
logic rst_n;
|
|
||||||
assign rst_n = ~rst;
|
|
||||||
|
|
||||||
// Для минимального теста держим все clock domain-ы на одном clock.
|
|
||||||
logic dac_clk_in;
|
|
||||||
logic adc_clk_in;
|
|
||||||
assign dac_clk_in = ctrl_clk;
|
|
||||||
assign adc_clk_in = ctrl_clk;
|
|
||||||
|
|
||||||
logic finish;
|
|
||||||
assign finish = 1'b0;
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// AXI-Lite flat -> axi4l_if
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
axi4l_if #(
|
|
||||||
.ADDR_W(ADDR_W),
|
|
||||||
.DATA_W(DATA_W),
|
|
||||||
.USER_W(USER_W)
|
|
||||||
) axil_bus (
|
|
||||||
.aclk(ctrl_clk),
|
|
||||||
.aresetn(rst_n)
|
|
||||||
);
|
|
||||||
|
|
||||||
axi4l_flat_to_if #(
|
|
||||||
.ADDR_W(ADDR_W),
|
|
||||||
.DATA_W(DATA_W),
|
|
||||||
.USER_W(USER_W)
|
|
||||||
) u_axil_flat_to_if (
|
|
||||||
.s_axil_awaddr (s_axil_awaddr),
|
|
||||||
.s_axil_awprot (s_axil_awprot),
|
|
||||||
.s_axil_awvalid(s_axil_awvalid),
|
|
||||||
.s_axil_awready(s_axil_awready),
|
|
||||||
|
|
||||||
.s_axil_wdata (s_axil_wdata),
|
|
||||||
.s_axil_wstrb (s_axil_wstrb),
|
|
||||||
.s_axil_wvalid (s_axil_wvalid),
|
|
||||||
.s_axil_wready (s_axil_wready),
|
|
||||||
|
|
||||||
.s_axil_bresp (s_axil_bresp),
|
|
||||||
.s_axil_bvalid (s_axil_bvalid),
|
|
||||||
.s_axil_bready (s_axil_bready),
|
|
||||||
|
|
||||||
.s_axil_araddr (s_axil_araddr),
|
|
||||||
.s_axil_arprot (s_axil_arprot),
|
|
||||||
.s_axil_arvalid(s_axil_arvalid),
|
|
||||||
.s_axil_arready(s_axil_arready),
|
|
||||||
|
|
||||||
.s_axil_rdata (s_axil_rdata),
|
|
||||||
.s_axil_rresp (s_axil_rresp),
|
|
||||||
.s_axil_rvalid (s_axil_rvalid),
|
|
||||||
.s_axil_rready (s_axil_rready),
|
|
||||||
|
|
||||||
.m_axil(axil_bus)
|
|
||||||
);
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// AXIS interfaces for the updated controller_wrapper_axil
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// AXIS READ DMA MASTER output
|
|
||||||
axis_if #(
|
|
||||||
.DATA_W (AXIS_DATA_WIDTH),
|
|
||||||
.KEEP_W (AXIS_KEEP_WIDTH),
|
|
||||||
.ID_W (AXIS_ID_WIDTH),
|
|
||||||
.DEST_W (AXIS_DEST_WIDTH),
|
|
||||||
.USER_W (AXIS_USER_WIDTH)
|
|
||||||
) dma_read_data (
|
|
||||||
.aclk(ctrl_clk),
|
|
||||||
.aresetn(rst_n)
|
|
||||||
);
|
|
||||||
|
|
||||||
logic [AXIS_KEEP_WIDTH-1:0] unused_read_tstrb;
|
|
||||||
|
|
||||||
axis_if_to_flat #(
|
|
||||||
.DATA_W (AXIS_DATA_WIDTH),
|
|
||||||
.KEEP_W (AXIS_KEEP_WIDTH),
|
|
||||||
.ID_W (AXIS_ID_WIDTH),
|
|
||||||
.DEST_W (AXIS_DEST_WIDTH),
|
|
||||||
.USER_W (AXIS_USER_WIDTH)
|
|
||||||
) u_read_data_if_to_flat (
|
|
||||||
.s_axis(dma_read_data),
|
|
||||||
|
|
||||||
.m_axis_tdata (m_axis_read_data_tdata),
|
|
||||||
.m_axis_tkeep (m_axis_read_data_tkeep),
|
|
||||||
.m_axis_tstrb (unused_read_tstrb),
|
|
||||||
.m_axis_tlast (m_axis_read_data_tlast),
|
|
||||||
.m_axis_tid (m_axis_read_data_tid),
|
|
||||||
.m_axis_tdest (m_axis_read_data_tdest),
|
|
||||||
.m_axis_tuser (m_axis_read_data_tuser),
|
|
||||||
.m_axis_tvalid(m_axis_read_data_tvalid),
|
|
||||||
.m_axis_tready(m_axis_read_data_tready)
|
|
||||||
);
|
|
||||||
|
|
||||||
// AXIS WRITE DMA SLAVE input
|
|
||||||
axis_if #(
|
|
||||||
.DATA_W (AXIS_DATA_WIDTH),
|
|
||||||
.KEEP_W (AXIS_KEEP_WIDTH),
|
|
||||||
.ID_W (AXIS_ID_WIDTH),
|
|
||||||
.DEST_W (AXIS_DEST_WIDTH),
|
|
||||||
.USER_W (AXIS_USER_WIDTH)
|
|
||||||
) dma_write_data (
|
|
||||||
.aclk(ctrl_clk),
|
|
||||||
.aresetn(rst_n)
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
axis_flat_to_if #(
|
|
||||||
.DATA_W (AXIS_DATA_WIDTH),
|
|
||||||
.KEEP_W (AXIS_KEEP_WIDTH),
|
|
||||||
.ID_W (AXIS_ID_WIDTH),
|
|
||||||
.DEST_W (AXIS_DEST_WIDTH),
|
|
||||||
.USER_W (AXIS_USER_WIDTH)
|
|
||||||
) u_write_data_flat_to_if (
|
|
||||||
.s_axis_tdata (s_axis_write_data_tdata),
|
|
||||||
.s_axis_tkeep (s_axis_write_data_tkeep),
|
|
||||||
.s_axis_tstrb (s_axis_write_data_tkeep),
|
|
||||||
.s_axis_tlast (s_axis_write_data_tlast),
|
|
||||||
.s_axis_tid (s_axis_write_data_tid),
|
|
||||||
.s_axis_tdest (s_axis_write_data_tdest),
|
|
||||||
.s_axis_tuser (s_axis_write_data_tuser),
|
|
||||||
.s_axis_tvalid(s_axis_write_data_tvalid),
|
|
||||||
.s_axis_tready(s_axis_write_data_tready),
|
|
||||||
|
|
||||||
.m_axis(dma_write_data)
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Controller ADC/DAC outputs.
|
|
||||||
logic [31:0] adc_window_size;
|
|
||||||
logic [31:0] dac_pulse_width;
|
|
||||||
logic [31:0] dac_pulse_period;
|
|
||||||
logic [DAC_DATA_WIDTH-1:0] dac_pulse_height;
|
|
||||||
logic [15:0] dac_pulse_num;
|
|
||||||
logic [31:0] adc_pulse_period;
|
|
||||||
logic [15:0] adc_pulse_num;
|
|
||||||
logic dac_start;
|
|
||||||
logic adc_start;
|
|
||||||
logic dac_rst;
|
|
||||||
logic adc_rst;
|
|
||||||
|
|
||||||
wrapper_controller_dma #(
|
|
||||||
.ADDR_W(ADDR_W),
|
|
||||||
.DATA_W(DATA_W),
|
|
||||||
.USER_W(USER_W),
|
|
||||||
.DAC_DATA_WIDTH(DAC_DATA_WIDTH),
|
|
||||||
.AXI_DATA_WIDTH(AXI_DATA_WIDTH),
|
|
||||||
.AXI_ID_WIDTH(AXI_ID_WIDTH),
|
|
||||||
.AXI_USER_WIDTH(AXI_USER_WIDTH),
|
|
||||||
.AXI_MAX_BURST_LEN(AXI_MAX_BURST_LEN),
|
|
||||||
.AXIS_LAST_ENABLE(AXIS_LAST_ENABLE),
|
|
||||||
.AXIS_ID_ENABLE(AXIS_ID_ENABLE),
|
|
||||||
.AXIS_DEST_ENABLE(AXIS_DEST_ENABLE),
|
|
||||||
.AXIS_USER_ENABLE(AXIS_USER_ENABLE),
|
|
||||||
.ENABLE_SG(ENABLE_SG),
|
|
||||||
.ENABLE_UNALIGNED(ENABLE_UNALIGNED)
|
|
||||||
) dut (
|
|
||||||
.ctrl_clk(ctrl_clk),
|
|
||||||
.dac_clk_in(dac_clk_in),
|
|
||||||
.adc_clk_in(adc_clk_in),
|
|
||||||
.rst_n(rst_n),
|
|
||||||
.s_axil(axil_bus),
|
|
||||||
|
|
||||||
.finish(finish),
|
|
||||||
.adc_window_size(adc_window_size),
|
|
||||||
|
|
||||||
.dac_pulse_width(dac_pulse_width),
|
|
||||||
.dac_pulse_period(dac_pulse_period),
|
|
||||||
.dac_pulse_height(dac_pulse_height),
|
|
||||||
.dac_pulse_num(dac_pulse_num),
|
|
||||||
|
|
||||||
.adc_pulse_period(adc_pulse_period),
|
|
||||||
.adc_pulse_num(adc_pulse_num),
|
|
||||||
|
|
||||||
.dac_start(dac_start),
|
|
||||||
.adc_start(adc_start),
|
|
||||||
.dac_rst(dac_rst),
|
|
||||||
.adc_rst(adc_rst),
|
|
||||||
|
|
||||||
.m_axis_read_data(dma_read_data),
|
|
||||||
.s_axis_write_data(dma_write_data)
|
|
||||||
);
|
|
||||||
|
|
||||||
endmodule : tb_controller_wrapper_axil
|
|
||||||
@@ -1,194 +0,0 @@
|
|||||||
import cocotb
|
|
||||||
from cocotb.clock import Clock
|
|
||||||
from cocotb.triggers import RisingEdge
|
|
||||||
from cocotbext.axi import AxiLiteBus, AxiLiteMaster
|
|
||||||
from cocotbext.axi import AxiBus, AxiRam, AxiStreamBus, AxiStreamSource, AxiStreamSink, AxiStreamFrame
|
|
||||||
|
|
||||||
|
|
||||||
# Register indexes from axi4l_reg_map_controller_pkg.sv
|
|
||||||
REG_CONTROL = 0
|
|
||||||
REG_STATUS = 1
|
|
||||||
REG_DAC_WIDTH = 2
|
|
||||||
REG_DAC_PERIOD = 3
|
|
||||||
REG_DAC_PULSE_NUM = 4
|
|
||||||
REG_DAC_PULSE_HEIGHT = 5
|
|
||||||
REG_ADC_PERIOD = 6
|
|
||||||
REG_WINDOW_SIZE = 7
|
|
||||||
REG_ERROR = 8
|
|
||||||
REG_DESC_READ_ADDR = 9
|
|
||||||
REG_DESC_READ_LEN = 10
|
|
||||||
REG_DESC_READ_CONFIG = 11
|
|
||||||
REG_READ_STATUS = 12
|
|
||||||
REG_DESC_WRITE_ADDR = 13
|
|
||||||
REG_DESC_WRITE_LEN_AND_TAG = 14
|
|
||||||
REG_STATUS_WRITE_LEN = 15
|
|
||||||
REG_STATUS_WRITE_CONFIG = 16
|
|
||||||
|
|
||||||
|
|
||||||
# REG_CONTROL pulse bits
|
|
||||||
CTRL_START = 0
|
|
||||||
CTRL_RST_SOFT = 1
|
|
||||||
CTRL_CFG_BUS_VALID = 2
|
|
||||||
CTRL_SEND_DESC_READ = 3
|
|
||||||
CTRL_SEND_DESC_WRITE = 4
|
|
||||||
CTRL_TAKE_STATUS_READ = 5
|
|
||||||
CTRL_TAKE_STATUS_WRITE = 6
|
|
||||||
|
|
||||||
|
|
||||||
def reg_addr(reg_index: int) -> int:
|
|
||||||
# AXI-Lite uses byte addresses, 32-bit registers are spaced by 4 bytes.
|
|
||||||
return reg_index * 4
|
|
||||||
|
|
||||||
|
|
||||||
def u32(value: int) -> bytes:
|
|
||||||
return int(value & 0xFFFFFFFF).to_bytes(4, "little")
|
|
||||||
|
|
||||||
|
|
||||||
class TB:
|
|
||||||
def __init__(self, dut):
|
|
||||||
self.dut = dut
|
|
||||||
|
|
||||||
cocotb.start_soon(Clock(dut.ctrl_clk, 10, units="ns").start())
|
|
||||||
|
|
||||||
self.axil = AxiLiteMaster(
|
|
||||||
AxiLiteBus.from_prefix(dut, "s_axil"),
|
|
||||||
dut.ctrl_clk,
|
|
||||||
dut.rst
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
self.axis_source = AxiStreamSource(
|
|
||||||
AxiStreamBus.from_prefix(dut, "s_axis_write_data"),
|
|
||||||
dut.ctrl_clk,
|
|
||||||
dut.rst
|
|
||||||
)
|
|
||||||
|
|
||||||
self.axis_sink = AxiStreamSink(
|
|
||||||
AxiStreamBus.from_prefix(dut, "m_axis_read_data"),
|
|
||||||
dut.ctrl_clk,
|
|
||||||
dut.rst
|
|
||||||
)
|
|
||||||
|
|
||||||
async def reset(self):
|
|
||||||
self.dut.rst.value = 1
|
|
||||||
for _ in range(5):
|
|
||||||
await RisingEdge(self.dut.ctrl_clk)
|
|
||||||
|
|
||||||
self.dut.rst.value = 0
|
|
||||||
for _ in range(5):
|
|
||||||
await RisingEdge(self.dut.ctrl_clk)
|
|
||||||
|
|
||||||
async def write_reg(self, reg_index: int, value: int):
|
|
||||||
await self.axil.write(reg_addr(reg_index), u32(value))
|
|
||||||
|
|
||||||
async def read_reg(self, reg_index: int) -> int:
|
|
||||||
resp = await self.axil.read(reg_addr(reg_index), 4)
|
|
||||||
return int.from_bytes(bytes(resp.data), "little")
|
|
||||||
|
|
||||||
|
|
||||||
@cocotb.test()
|
|
||||||
async def simple_axil_write_read(dut):
|
|
||||||
tb = TB(dut)
|
|
||||||
await tb.reset()
|
|
||||||
|
|
||||||
await tb.write_reg(REG_DAC_WIDTH, 0x0000_0123)
|
|
||||||
|
|
||||||
value = await tb.read_reg(REG_DAC_WIDTH)
|
|
||||||
assert value == 0x0000_0123
|
|
||||||
|
|
||||||
|
|
||||||
@cocotb.test()
|
|
||||||
async def simple_controller_config_write(dut):
|
|
||||||
tb = TB(dut)
|
|
||||||
await tb.reset()
|
|
||||||
|
|
||||||
await tb.write_reg(REG_DAC_WIDTH, 0x10)
|
|
||||||
await tb.write_reg(REG_DAC_PERIOD, 0x40)
|
|
||||||
await tb.write_reg(REG_DAC_PULSE_NUM, 3)
|
|
||||||
await tb.write_reg(REG_DAC_PULSE_HEIGHT, 0x7FF)
|
|
||||||
await tb.write_reg(REG_ADC_PERIOD, 0x80)
|
|
||||||
await tb.write_reg(REG_WINDOW_SIZE, 16)
|
|
||||||
|
|
||||||
assert await tb.read_reg(REG_DAC_WIDTH) == 0x10
|
|
||||||
assert await tb.read_reg(REG_WINDOW_SIZE) == 16
|
|
||||||
|
|
||||||
# write data: set cfg_bus_valid signal
|
|
||||||
await tb.write_reg(REG_CONTROL, 1 << CTRL_CFG_BUS_VALID)
|
|
||||||
|
|
||||||
# wait
|
|
||||||
for _ in range(30):
|
|
||||||
await RisingEdge(dut.ctrl_clk)
|
|
||||||
|
|
||||||
# check config
|
|
||||||
assert int(dut.dac_pulse_width) == 0x10
|
|
||||||
assert int(dut.dac_pulse_period) == 0x40
|
|
||||||
assert int(dut.dac_pulse_num) == 3
|
|
||||||
assert int(dut.dac_pulse_height) == 0x7FF
|
|
||||||
assert int(dut.adc_pulse_period) == 0x80
|
|
||||||
assert int(dut.adc_window_size) == 16
|
|
||||||
|
|
||||||
await RisingEdge(dut.ctrl_clk)
|
|
||||||
|
|
||||||
|
|
||||||
@cocotb.test()
|
|
||||||
async def simple_controller_start_check(dut):
|
|
||||||
tb = TB(dut)
|
|
||||||
await tb.reset()
|
|
||||||
await tb.write_reg(REG_CONTROL, 1 << CTRL_START)
|
|
||||||
|
|
||||||
await RisingEdge(dut.dac_start)
|
|
||||||
|
|
||||||
@cocotb.test()
|
|
||||||
async def simple_dma_mem_to_mem(dut):
|
|
||||||
tb = TB(dut)
|
|
||||||
await tb.reset()
|
|
||||||
|
|
||||||
SRC_ADDR = 0x1000
|
|
||||||
LENGTH = 8
|
|
||||||
|
|
||||||
tx_data = bytes([ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 ])
|
|
||||||
|
|
||||||
## write part
|
|
||||||
|
|
||||||
await tb.write_reg(REG_DESC_WRITE_ADDR, SRC_ADDR)
|
|
||||||
await tb.write_reg(REG_DESC_WRITE_LEN_AND_TAG, LENGTH)
|
|
||||||
|
|
||||||
await tb.write_reg(REG_CONTROL, 1 << CTRL_SEND_DESC_WRITE)
|
|
||||||
|
|
||||||
await tb.axis_source.send(AxiStreamFrame(tx_data))
|
|
||||||
|
|
||||||
for _ in range(20):
|
|
||||||
await RisingEdge(dut.ctrl_clk)
|
|
||||||
|
|
||||||
await tb.write_reg(REG_CONTROL, 1 << CTRL_TAKE_STATUS_WRITE)
|
|
||||||
|
|
||||||
for _ in range(10):
|
|
||||||
await RisingEdge(dut.ctrl_clk)
|
|
||||||
|
|
||||||
|
|
||||||
assert await tb.read_reg(REG_STATUS_WRITE_CONFIG) == 0
|
|
||||||
assert await tb.read_reg(REG_STATUS_WRITE_LEN) == 0x8
|
|
||||||
|
|
||||||
## read part
|
|
||||||
|
|
||||||
await tb.write_reg(REG_DESC_READ_ADDR, SRC_ADDR)
|
|
||||||
await tb.write_reg(REG_DESC_READ_LEN, LENGTH)
|
|
||||||
await tb.write_reg(REG_DESC_READ_CONFIG, 0x0000_0001)
|
|
||||||
|
|
||||||
await tb.write_reg(REG_CONTROL, 1 << CTRL_SEND_DESC_READ)
|
|
||||||
|
|
||||||
rx_frame = await tb.axis_sink.recv()
|
|
||||||
|
|
||||||
for _ in range(20):
|
|
||||||
await RisingEdge(dut.ctrl_clk)
|
|
||||||
|
|
||||||
await tb.write_reg(REG_CONTROL, 1 << CTRL_TAKE_STATUS_READ)
|
|
||||||
|
|
||||||
for _ in range(10):
|
|
||||||
await RisingEdge(dut.ctrl_clk)
|
|
||||||
|
|
||||||
assert await tb.read_reg(REG_READ_STATUS) == 0x1
|
|
||||||
|
|
||||||
assert bytes(rx_frame) == tx_data
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Primary clocks
|
|
||||||
create_clock -name eth_clk -period 8.000 [get_ports eth_clk_in]
|
|
||||||
create_clock -name dac_clk -period 7.692 [get_ports dac_clk_in]
|
|
||||||
create_clock -name adc_clk -period 15.385 [get_ports adc_clk_in]
|
|
||||||
|
|
||||||
|
|
||||||
# Asynchronous clock groups
|
|
||||||
# eth, dac, adc are independent domains
|
|
||||||
|
|
||||||
set_clock_groups -name ASYNC_ETH_DAC_ADC -asynchronous \
|
|
||||||
-group [get_clocks eth_clk] \
|
|
||||||
-group [get_clocks dac_clk] \
|
|
||||||
-group [get_clocks adc_clk]
|
|
||||||
Vendored
-1
Submodule external/rtl_libs deleted from e4311214eb
@@ -1,122 +0,0 @@
|
|||||||
module axi4l_reg_map_controller #(
|
|
||||||
parameter int unsigned ADDR_W = 16,
|
|
||||||
parameter int unsigned DATA_W = 32,
|
|
||||||
parameter int unsigned USER_W = 1
|
|
||||||
)(
|
|
||||||
input logic clk,
|
|
||||||
input logic rst_n,
|
|
||||||
axi4l_if.slave s_axil,
|
|
||||||
// dac adc registers
|
|
||||||
output logic start_o,
|
|
||||||
output logic cfg_bus_valid_o,
|
|
||||||
output logic [31:0] pulse_width_o,
|
|
||||||
output logic [31:0] pulse_period_o,
|
|
||||||
output logic [31:0] pulse_num_o,
|
|
||||||
output logic [31:0] pulse_height_raw_o,
|
|
||||||
output logic [31:0] pulse_period_ADC_o,
|
|
||||||
output logic [31:0] window_size_o,
|
|
||||||
|
|
||||||
// DMA CONTROL SIGNALS
|
|
||||||
output logic send_desc_read_o,
|
|
||||||
output logic send_desc_write_o,
|
|
||||||
output logic take_status_read_o,
|
|
||||||
output logic take_status_write_o,
|
|
||||||
|
|
||||||
input logic desc_read_dma_busy_i,
|
|
||||||
input logic desc_write_dma_busy_i,
|
|
||||||
input logic status_read_dma_busy_i,
|
|
||||||
input logic status_write_dma_busy_i,
|
|
||||||
|
|
||||||
input logic desc_read_dma_hs_i,
|
|
||||||
input logic desc_write_dma_hs_i,
|
|
||||||
input logic status_read_dma_hs_i,
|
|
||||||
input logic status_write_dma_hs_i,
|
|
||||||
|
|
||||||
// DMA read descriptors and status register
|
|
||||||
|
|
||||||
output logic [31:0] desc_read_addr_o,
|
|
||||||
output logic [31:0] desc_read_len_o,
|
|
||||||
output logic [31:0] desc_read_config_o,
|
|
||||||
|
|
||||||
input logic [31:0] status_read_i,
|
|
||||||
|
|
||||||
// DMA write descriptors and status register
|
|
||||||
output logic [31:0] desc_write_addr_o,
|
|
||||||
output logic [31:0] desc_write_len_and_tag_o,
|
|
||||||
|
|
||||||
input logic [31:0] status_write_len_i,
|
|
||||||
input logic [31:0] status_write_config_i,
|
|
||||||
|
|
||||||
output logic rst_soft_o,
|
|
||||||
input logic busy_i,
|
|
||||||
input logic [7:0] error_code_i
|
|
||||||
);
|
|
||||||
import axi4l_reg_map_controller_pkg::*;
|
|
||||||
localparam int unsigned N_REGS = CTRL_REG_MAP_N_REGS;
|
|
||||||
|
|
||||||
logic [N_REGS-1:0][31:0] reg_i;
|
|
||||||
logic [N_REGS-1:0][31:0] reg_o;
|
|
||||||
logic [N_REGS-1:0][31:0] reg_pulse;
|
|
||||||
|
|
||||||
axi4l_reg_map #(
|
|
||||||
.ADDR_W (ADDR_W),
|
|
||||||
.DATA_W (DATA_W),
|
|
||||||
.USER_W (USER_W),
|
|
||||||
.N_REGS (N_REGS),
|
|
||||||
.REG_MODE (CTRL_REG_MAP_REG_MODE),
|
|
||||||
.REG_RST (CTRL_REG_MAP_REG_RST)
|
|
||||||
) u_reg_map (
|
|
||||||
.clk (clk),
|
|
||||||
.rst_n (rst_n),
|
|
||||||
.s_axil (s_axil),
|
|
||||||
.reg_i (reg_i),
|
|
||||||
.reg_o (reg_o),
|
|
||||||
.reg_pulse(reg_pulse)
|
|
||||||
);
|
|
||||||
|
|
||||||
always_comb begin
|
|
||||||
reg_i = '0;
|
|
||||||
|
|
||||||
reg_i[REG_STATUS][0] = busy_i;
|
|
||||||
|
|
||||||
reg_i[REG_STATUS][1] = desc_read_dma_busy_i;
|
|
||||||
reg_i[REG_STATUS][2] = desc_write_dma_busy_i;
|
|
||||||
reg_i[REG_STATUS][3] = status_read_dma_busy_i;
|
|
||||||
reg_i[REG_STATUS][4] = status_write_dma_busy_i;
|
|
||||||
|
|
||||||
reg_i[REG_STATUS][5] = desc_read_dma_hs_i;
|
|
||||||
reg_i[REG_STATUS][6] = desc_write_dma_hs_i;
|
|
||||||
reg_i[REG_STATUS][7] = status_read_dma_hs_i;
|
|
||||||
reg_i[REG_STATUS][8] = status_write_dma_hs_i;
|
|
||||||
|
|
||||||
reg_i[REG_ERROR][7:0] = error_code_i;
|
|
||||||
|
|
||||||
reg_i[REG_READ_STATUS] = status_read_i;
|
|
||||||
reg_i[REG_STATUS_WRITE_LEN] = status_write_len_i;
|
|
||||||
reg_i[REG_STATUS_WRITE_CONFIG] = status_write_config_i;
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
assign start_o = reg_pulse[REG_CONTROL][0];
|
|
||||||
assign rst_soft_o = reg_pulse[REG_CONTROL][1];
|
|
||||||
assign cfg_bus_valid_o = reg_pulse[REG_CONTROL][2];
|
|
||||||
|
|
||||||
assign send_desc_read_o = reg_pulse[REG_CONTROL][3];
|
|
||||||
assign send_desc_write_o = reg_pulse[REG_CONTROL][4];
|
|
||||||
assign take_status_read_o = reg_pulse[REG_CONTROL][5];
|
|
||||||
assign take_status_write_o = reg_pulse[REG_CONTROL][6];
|
|
||||||
|
|
||||||
assign pulse_width_o = reg_o[REG_DAC_WIDTH];
|
|
||||||
assign pulse_period_o = reg_o[REG_DAC_PERIOD];
|
|
||||||
assign pulse_num_o = reg_o[REG_DAC_PULSE_NUM];
|
|
||||||
assign pulse_height_raw_o = reg_o[REG_DAC_PULSE_HEIGHT];
|
|
||||||
assign pulse_period_ADC_o = reg_o[REG_ADC_PERIOD];
|
|
||||||
assign window_size_o = reg_o[REG_WINDOW_SIZE];
|
|
||||||
|
|
||||||
assign desc_read_addr_o = reg_o[REG_DESC_READ_ADDR];
|
|
||||||
assign desc_read_len_o = reg_o[REG_DESC_READ_LEN];
|
|
||||||
assign desc_read_config_o = reg_o[REG_DESC_READ_CONFIG];
|
|
||||||
assign desc_write_addr_o = reg_o[REG_DESC_WRITE_ADDR];
|
|
||||||
assign desc_write_len_and_tag_o = reg_o[REG_DESC_WRITE_LEN_AND_TAG];
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
package axi4l_reg_map_controller_pkg;
|
|
||||||
|
|
||||||
localparam int unsigned CTRL_REG_MAP_N_REGS = 17;
|
|
||||||
|
|
||||||
/*
|
|
||||||
dac adc configuration registers
|
|
||||||
*/
|
|
||||||
localparam logic [31:0] REG_CONTROL = 32'd0;
|
|
||||||
localparam logic [31:0] REG_STATUS = 32'd1;
|
|
||||||
localparam logic [31:0] REG_DAC_WIDTH = 32'd2;
|
|
||||||
localparam logic [31:0] REG_DAC_PERIOD = 32'd3;
|
|
||||||
localparam logic [31:0] REG_DAC_PULSE_NUM = 32'd4;
|
|
||||||
localparam logic [31:0] REG_DAC_PULSE_HEIGHT = 32'd5;
|
|
||||||
localparam logic [31:0] REG_ADC_PERIOD = 32'd6;
|
|
||||||
localparam logic [31:0] REG_WINDOW_SIZE = 32'd7;
|
|
||||||
localparam logic [31:0] REG_ERROR = 32'd8;
|
|
||||||
|
|
||||||
/*
|
|
||||||
AXI read descriptor input and AXI read descriptor status output configuration registers
|
|
||||||
*/
|
|
||||||
localparam logic [31:0] REG_DESC_READ_ADDR = 32'd9;
|
|
||||||
localparam logic [31:0] REG_DESC_READ_LEN = 32'd10;
|
|
||||||
localparam logic [31:0] REG_DESC_READ_CONFIG = 32'd11;
|
|
||||||
|
|
||||||
localparam logic [31:0] REG_READ_STATUS = 32'd12;
|
|
||||||
|
|
||||||
/*
|
|
||||||
AXI write descriptor input and AXI write descriptor status output configuration registers
|
|
||||||
*/
|
|
||||||
localparam logic [31:0] REG_DESC_WRITE_ADDR = 32'd13;
|
|
||||||
localparam logic [31:0] REG_DESC_WRITE_LEN_AND_TAG = 32'd14;
|
|
||||||
|
|
||||||
localparam logic [31:0] REG_STATUS_WRITE_LEN = 32'd15;
|
|
||||||
localparam logic [31:0] REG_STATUS_WRITE_CONFIG = 32'd16;
|
|
||||||
|
|
||||||
|
|
||||||
localparam logic [2:0] REG_BIT_RSVD = 3'd0;
|
|
||||||
localparam logic [2:0] REG_BIT_RO = 3'd1;
|
|
||||||
localparam logic [2:0] REG_BIT_RW = 3'd2;
|
|
||||||
localparam logic [2:0] REG_BIT_W1S = 3'd3;
|
|
||||||
|
|
||||||
localparam logic [CTRL_REG_MAP_N_REGS-1:0][31:0][2:0] CTRL_REG_MAP_REG_MODE = '{
|
|
||||||
default: '{default: REG_BIT_RSVD},
|
|
||||||
|
|
||||||
REG_CONTROL: '{
|
|
||||||
0 : REG_BIT_W1S,
|
|
||||||
1 : REG_BIT_W1S,
|
|
||||||
2 : REG_BIT_W1S,
|
|
||||||
3 : REG_BIT_W1S,
|
|
||||||
4 : REG_BIT_W1S,
|
|
||||||
5 : REG_BIT_W1S,
|
|
||||||
6 : REG_BIT_W1S,
|
|
||||||
default: REG_BIT_RSVD
|
|
||||||
},
|
|
||||||
|
|
||||||
REG_STATUS: '{
|
|
||||||
0 : REG_BIT_RO,
|
|
||||||
1 : REG_BIT_RO,
|
|
||||||
2 : REG_BIT_RO,
|
|
||||||
3 : REG_BIT_RO,
|
|
||||||
4 : REG_BIT_RO,
|
|
||||||
5 : REG_BIT_RO,
|
|
||||||
6 : REG_BIT_RO,
|
|
||||||
7 : REG_BIT_RO,
|
|
||||||
8 : REG_BIT_RO,
|
|
||||||
default: REG_BIT_RSVD
|
|
||||||
},
|
|
||||||
|
|
||||||
REG_DAC_WIDTH: '{default: REG_BIT_RW},
|
|
||||||
REG_DAC_PERIOD: '{default: REG_BIT_RW},
|
|
||||||
REG_DAC_PULSE_NUM: '{default: REG_BIT_RW},
|
|
||||||
REG_DAC_PULSE_HEIGHT: '{default: REG_BIT_RW},
|
|
||||||
REG_ADC_PERIOD: '{default: REG_BIT_RW},
|
|
||||||
REG_WINDOW_SIZE: '{default: REG_BIT_RW},
|
|
||||||
|
|
||||||
REG_ERROR: '{default: REG_BIT_RO},
|
|
||||||
|
|
||||||
REG_DESC_READ_ADDR: '{default: REG_BIT_RW},
|
|
||||||
REG_DESC_READ_LEN: '{default: REG_BIT_RW},
|
|
||||||
REG_DESC_READ_CONFIG: '{default: REG_BIT_RW},
|
|
||||||
REG_READ_STATUS: '{default: REG_BIT_RO},
|
|
||||||
|
|
||||||
REG_DESC_WRITE_ADDR: '{default: REG_BIT_RW},
|
|
||||||
REG_DESC_WRITE_LEN_AND_TAG: '{default: REG_BIT_RW},
|
|
||||||
REG_STATUS_WRITE_LEN: '{default: REG_BIT_RO},
|
|
||||||
REG_STATUS_WRITE_CONFIG: '{default: REG_BIT_RO}
|
|
||||||
};
|
|
||||||
|
|
||||||
localparam logic [CTRL_REG_MAP_N_REGS-1:0][31:0] CTRL_REG_MAP_REG_RST = '{
|
|
||||||
32'h0000_0000,
|
|
||||||
32'h0000_0000,
|
|
||||||
32'h0000_0000,
|
|
||||||
32'h0000_0000,
|
|
||||||
32'h0000_0000,
|
|
||||||
32'h0000_0000,
|
|
||||||
32'h0000_0000,
|
|
||||||
32'h0000_0000,
|
|
||||||
32'h0000_0000,
|
|
||||||
32'h0000_0000,
|
|
||||||
32'h0000_0000,
|
|
||||||
32'h0000_0000,
|
|
||||||
32'h0000_0000,
|
|
||||||
32'h0000_0000,
|
|
||||||
32'h0000_0000,
|
|
||||||
32'h0000_0000,
|
|
||||||
32'h0000_0000
|
|
||||||
};
|
|
||||||
|
|
||||||
endpackage
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
module axis_defaults_master
|
|
||||||
(
|
|
||||||
axis_if.master axis
|
|
||||||
);
|
|
||||||
|
|
||||||
assign axis.req.t.keep = '1;
|
|
||||||
assign axis.req.t.strb = '1;
|
|
||||||
assign axis.req.t.last = 1'b1;
|
|
||||||
assign axis.req.t.id = '0;
|
|
||||||
assign axis.req.t.dest = '0;
|
|
||||||
assign axis.req.t.user = '0;
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
@@ -1,21 +1,19 @@
|
|||||||
module control #(
|
module control #(
|
||||||
parameter int unsigned DAC_DATA_WIDTH = 12
|
parameter int unsigned DAC_DATA_WIDTH = 12
|
||||||
) (
|
) (
|
||||||
input logic ctrl_clk,
|
input logic eth_clk_in,
|
||||||
input logic dac_clk_in,
|
input logic dac_clk_in,
|
||||||
input logic adc_clk_in,
|
input logic adc_clk_in,
|
||||||
|
|
||||||
input logic rst_n,
|
input logic rst_n,
|
||||||
input logic rst_soft,
|
|
||||||
|
// AXI stream slave, eth_clk_in domain
|
||||||
|
input logic [7:0] s_axis_tdata,
|
||||||
|
input logic s_axis_tvalid,
|
||||||
|
output logic s_axis_tready,
|
||||||
|
input logic s_axis_tlast,
|
||||||
|
|
||||||
// adc_clk_in domain
|
// adc_clk_in domain
|
||||||
input logic finish,
|
input logic finish,
|
||||||
input logic [159:0] cfg_bus_input,
|
|
||||||
input logic cfg_bus_valid,
|
|
||||||
input logic start,
|
|
||||||
|
|
||||||
// status signals
|
|
||||||
output logic busy,
|
|
||||||
|
|
||||||
// dac_clk_in domain outputs
|
// dac_clk_in domain outputs
|
||||||
output logic [31:0] dac_pulse_width,
|
output logic [31:0] dac_pulse_width,
|
||||||
@@ -26,7 +24,6 @@ module control #(
|
|||||||
// adc_clk_in domain outputs
|
// adc_clk_in domain outputs
|
||||||
output logic [31:0] adc_pulse_period,
|
output logic [31:0] adc_pulse_period,
|
||||||
output logic [15:0] adc_pulse_num,
|
output logic [15:0] adc_pulse_num,
|
||||||
output logic [31:0] adc_window_size,
|
|
||||||
|
|
||||||
// pulse outputs
|
// pulse outputs
|
||||||
output logic dac_start,
|
output logic dac_start,
|
||||||
@@ -45,22 +42,27 @@ module control #(
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
// command constants
|
||||||
|
localparam logic [7:0] CMD_SOFT_RESET = 8'h0F;
|
||||||
|
localparam logic [7:0] CMD_START = 8'hF0;
|
||||||
|
localparam logic [7:0] CMD_SET_DATA = 8'h88;
|
||||||
|
|
||||||
// reset synchronizers: async assert, sync deassert in each domain
|
// reset synchronizers: async assert, sync deassert in each domain
|
||||||
logic rst_ff1, rst_ff2;
|
logic eth_rst_ff1, eth_rst_ff2;
|
||||||
logic dac_rst_ff1, dac_rst_ff2;
|
logic dac_rst_ff1, dac_rst_ff2;
|
||||||
logic adc_rst_ff1, adc_rst_ff2;
|
logic adc_rst_ff1, adc_rst_ff2;
|
||||||
|
|
||||||
logic ctrl_rst;
|
logic eth_rst;
|
||||||
logic dac_rst_int;
|
logic dac_rst_int;
|
||||||
logic adc_rst_int;
|
logic adc_rst_int;
|
||||||
|
|
||||||
always_ff @(posedge ctrl_clk or negedge rst_n) begin
|
always_ff @(posedge eth_clk_in or negedge rst_n) begin
|
||||||
if (!rst_n) begin
|
if (!rst_n) begin
|
||||||
rst_ff1 <= 1'b1;
|
eth_rst_ff1 <= 1'b1;
|
||||||
rst_ff2 <= 1'b1;
|
eth_rst_ff2 <= 1'b1;
|
||||||
end else begin
|
end else begin
|
||||||
rst_ff1 <= 1'b0;
|
eth_rst_ff1 <= 1'b0;
|
||||||
rst_ff2 <= rst_ff1;
|
eth_rst_ff2 <= eth_rst_ff1;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -84,34 +86,74 @@ module control #(
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
assign ctrl_rst = rst_ff2;
|
assign eth_rst = eth_rst_ff2;
|
||||||
assign dac_rst_int = dac_rst_ff2;
|
assign dac_rst_int = dac_rst_ff2;
|
||||||
assign adc_rst_int = adc_rst_ff2;
|
assign adc_rst_int = adc_rst_ff2;
|
||||||
|
|
||||||
|
// axi stream is always accepted. If packet is not needed, it is discarded.
|
||||||
|
assign s_axis_tready = 1'b1;
|
||||||
|
|
||||||
|
(* MARK_DEBUG="true" *) wire axis_hs = s_axis_tvalid & s_axis_tready;
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
// Shared 96-bit config bus in ETH domain
|
||||||
|
//
|
||||||
|
// Byte order for SET_DATA payload, little-endian:
|
||||||
|
// payload byte 0 -> cfg_bus_eth[7:0]
|
||||||
|
// payload byte 1 -> cfg_bus_eth[15:8]
|
||||||
|
// ...etc...
|
||||||
|
// payload byte 11 -> cfg_bus_eth[95:88]
|
||||||
|
//
|
||||||
|
// Field layout inside cfg_bus_eth:
|
||||||
|
// [31:0] pulse_width
|
||||||
|
// [63:32] pulse_period
|
||||||
|
// [79:64] pulse_num
|
||||||
|
// [95:80] pulse_height_raw[15:0]
|
||||||
|
// [127:96] pulse_period_ADC
|
||||||
|
//
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
(* MARK_DEBUG="true" *) logic [127:0] cfg_bus_eth;
|
||||||
|
logic [127:0] cfg_shift_eth;
|
||||||
|
|
||||||
|
// ETH-domain parser and control
|
||||||
|
typedef enum logic [2:0] {
|
||||||
|
ST_IDLE = 3'd0,
|
||||||
|
ST_RECV_CFG = 3'd1,
|
||||||
|
ST_WAIT_CFG_ACK = 3'd2,
|
||||||
|
ST_DISCARD = 3'd3
|
||||||
|
} eth_state_t;
|
||||||
|
|
||||||
|
(* MARK_DEBUG="true" *) eth_state_t eth_state;
|
||||||
|
|
||||||
|
logic [3:0] cfg_byte_cnt;
|
||||||
|
|
||||||
|
// Busy flag: set by START command, cleared by finish event from ADC domain
|
||||||
|
(* MARK_DEBUG="true" *) logic busy_flag_eth;
|
||||||
|
|
||||||
// Pending ACKs for config delivery
|
// Pending ACKs for config delivery
|
||||||
logic cfg_wait_dac_ack;
|
logic cfg_wait_dac_ack;
|
||||||
logic cfg_wait_adc_ack;
|
logic cfg_wait_adc_ack;
|
||||||
|
|
||||||
// Event toggles cntrl -> DAC/ADC
|
// Event toggles ETH -> DAC/ADC
|
||||||
logic start_toggle;
|
logic start_toggle_eth;
|
||||||
logic rst_toggle;
|
logic rst_toggle_eth;
|
||||||
|
|
||||||
// Config request toggles cntrl -> DAC/ADC
|
// Config request toggles ETH -> DAC/ADC
|
||||||
logic cfg_req_toggle_dac;
|
logic cfg_req_toggle_dac_eth;
|
||||||
logic cfg_req_toggle_adc;
|
logic cfg_req_toggle_adc_eth;
|
||||||
|
|
||||||
// ACK toggles DAC/ADC -> cntrl
|
// ACK toggles DAC/ADC -> ETH
|
||||||
logic cfg_ack_toggle_dac;
|
logic cfg_ack_toggle_dac;
|
||||||
logic cfg_ack_toggle_adc;
|
logic cfg_ack_toggle_adc;
|
||||||
|
|
||||||
(* ASYNC_REG = "TRUE" *) logic cfg_ack_toggle_dac_meta, cfg_ack_toggle_dac_sync, cfg_ack_toggle_dac_sync_d;
|
(* ASYNC_REG = "TRUE" *) logic cfg_ack_toggle_dac_meta, cfg_ack_toggle_dac_sync, cfg_ack_toggle_dac_sync_d;
|
||||||
(* ASYNC_REG = "TRUE" *) logic cfg_ack_toggle_adc_meta, cfg_ack_toggle_adc_sync, cfg_ack_toggle_adc_sync_d;
|
(* ASYNC_REG = "TRUE" *) logic cfg_ack_toggle_adc_meta, cfg_ack_toggle_adc_sync, cfg_ack_toggle_adc_sync_d;
|
||||||
|
|
||||||
wire cfg_ack_pulse_dac = cfg_ack_toggle_dac_sync ^ cfg_ack_toggle_dac_sync_d;
|
wire cfg_ack_pulse_dac_eth = cfg_ack_toggle_dac_sync ^ cfg_ack_toggle_dac_sync_d;
|
||||||
wire cfg_ack_pulse_adc = cfg_ack_toggle_adc_sync ^ cfg_ack_toggle_adc_sync_d;
|
wire cfg_ack_pulse_adc_eth = cfg_ack_toggle_adc_sync ^ cfg_ack_toggle_adc_sync_d;
|
||||||
|
|
||||||
always_ff @(posedge ctrl_clk or posedge ctrl_rst) begin
|
always_ff @(posedge eth_clk_in or posedge eth_rst) begin
|
||||||
if (ctrl_rst) begin
|
if (eth_rst) begin
|
||||||
cfg_ack_toggle_dac_meta <= 1'b0;
|
cfg_ack_toggle_dac_meta <= 1'b0;
|
||||||
cfg_ack_toggle_dac_sync <= 1'b0;
|
cfg_ack_toggle_dac_sync <= 1'b0;
|
||||||
cfg_ack_toggle_dac_sync_d <= 1'b0;
|
cfg_ack_toggle_dac_sync_d <= 1'b0;
|
||||||
@@ -130,11 +172,11 @@ module control #(
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
// finish event: ADC -> cntrl via toggle CDC
|
// finish event: ADC -> ETH via toggle CDC
|
||||||
logic finish_toggle_adc;
|
logic finish_toggle_adc;
|
||||||
logic finish_meta, finish_sync, finish_sync_d;
|
logic finish_meta_eth, finish_sync_eth, finish_sync_eth_d;
|
||||||
|
|
||||||
wire finish_pulse = finish_sync ^ finish_sync_d;
|
wire finish_pulse_eth = finish_sync_eth ^ finish_sync_eth_d;
|
||||||
|
|
||||||
always_ff @(posedge adc_clk_in or posedge adc_rst_int) begin
|
always_ff @(posedge adc_clk_in or posedge adc_rst_int) begin
|
||||||
if (adc_rst_int) begin
|
if (adc_rst_int) begin
|
||||||
@@ -144,66 +186,152 @@ module control #(
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
always_ff @(posedge ctrl_clk or posedge ctrl_rst) begin
|
always_ff @(posedge eth_clk_in or posedge eth_rst) begin
|
||||||
if (ctrl_rst) begin
|
if (eth_rst) begin
|
||||||
finish_meta <= 1'b0;
|
finish_meta_eth <= 1'b0;
|
||||||
finish_sync <= 1'b0;
|
finish_sync_eth <= 1'b0;
|
||||||
finish_sync_d <= 1'b0;
|
finish_sync_eth_d <= 1'b0;
|
||||||
end else begin
|
end else begin
|
||||||
finish_meta <= finish_toggle_adc;
|
finish_meta_eth <= finish_toggle_adc;
|
||||||
finish_sync <= finish_meta;
|
finish_sync_eth <= finish_meta_eth;
|
||||||
finish_sync_d <= finish_sync;
|
finish_sync_eth_d <= finish_sync_eth;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
logic [159:0] cfg_bus;
|
// ETH FSM
|
||||||
|
always_ff @(posedge eth_clk_in or posedge eth_rst) begin
|
||||||
|
if (eth_rst) begin
|
||||||
|
eth_state <= ST_IDLE;
|
||||||
|
cfg_byte_cnt <= '0;
|
||||||
|
cfg_shift_eth <= '0;
|
||||||
|
cfg_bus_eth <= '0;
|
||||||
|
|
||||||
always_ff @(posedge ctrl_clk or posedge ctrl_rst) begin
|
busy_flag_eth <= 1'b0;
|
||||||
if (ctrl_rst) begin
|
|
||||||
cfg_bus <= '0;
|
|
||||||
busy <= 0;
|
|
||||||
|
|
||||||
start_toggle <= 0;
|
start_toggle_eth <= 1'b0;
|
||||||
rst_toggle <= 0;
|
rst_toggle_eth <= 1'b0;
|
||||||
|
|
||||||
cfg_req_toggle_dac <= 0;
|
cfg_req_toggle_dac_eth <= 1'b0;
|
||||||
cfg_req_toggle_adc <= 0;
|
cfg_req_toggle_adc_eth <= 1'b0;
|
||||||
|
|
||||||
cfg_wait_dac_ack <= 0;
|
cfg_wait_dac_ack <= 1'b0;
|
||||||
cfg_wait_adc_ack <= 0;
|
cfg_wait_adc_ack <= 1'b0;
|
||||||
end else begin
|
end else begin
|
||||||
if (finish_pulse) begin
|
// finish always clears busy
|
||||||
busy <= 0;
|
if (finish_pulse_eth) begin
|
||||||
|
busy_flag_eth <= 1'b0;
|
||||||
end
|
end
|
||||||
if (cfg_ack_pulse_dac) begin
|
|
||||||
|
// config acks
|
||||||
|
if (cfg_ack_pulse_dac_eth) begin
|
||||||
cfg_wait_dac_ack <= 1'b0;
|
cfg_wait_dac_ack <= 1'b0;
|
||||||
end
|
end
|
||||||
if (cfg_ack_pulse_adc) begin
|
if (cfg_ack_pulse_adc_eth) begin
|
||||||
cfg_wait_adc_ack <= 1'b0;
|
cfg_wait_adc_ack <= 1'b0;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (cfg_bus_valid && !busy && !cfg_wait_dac_ack && !cfg_wait_adc_ack) begin
|
case (eth_state)
|
||||||
cfg_bus <= cfg_bus_input;
|
ST_IDLE: begin
|
||||||
|
cfg_byte_cnt <= '0;
|
||||||
|
cfg_shift_eth <= cfg_shift_eth;
|
||||||
|
|
||||||
cfg_req_toggle_dac <= ~cfg_req_toggle_dac;
|
if (axis_hs) begin
|
||||||
cfg_req_toggle_adc <= ~cfg_req_toggle_adc;
|
// if busy, drop the whole packet
|
||||||
|
if (busy_flag_eth) begin
|
||||||
cfg_wait_dac_ack <= 1;
|
if (!s_axis_tlast) begin
|
||||||
cfg_wait_adc_ack <= 1;
|
eth_state <= ST_DISCARD;
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
|
unique case (s_axis_tdata)
|
||||||
|
CMD_SOFT_RESET: begin
|
||||||
|
rst_toggle_eth <= ~rst_toggle_eth;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (start && !busy && !cfg_wait_dac_ack && !cfg_wait_adc_ack) begin
|
CMD_START: begin
|
||||||
start_toggle <= ~start_toggle;
|
start_toggle_eth <= ~start_toggle_eth;
|
||||||
busy <= 1;
|
busy_flag_eth <= 1'b1;
|
||||||
end
|
|
||||||
if (rst_soft) begin
|
|
||||||
rst_toggle <= ~rst_toggle;
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
CMD_SET_DATA: begin
|
||||||
|
// expect exactly 12 bytes after command
|
||||||
|
if (s_axis_tlast) begin
|
||||||
|
// no payload, invalid packet
|
||||||
|
eth_state <= ST_IDLE;
|
||||||
|
end else begin
|
||||||
|
cfg_byte_cnt <= 4'd0;
|
||||||
|
cfg_shift_eth <= '0;
|
||||||
|
eth_state <= ST_RECV_CFG;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
// cntrl -> DAC: start/reset event sync
|
default: begin
|
||||||
|
// unknown command: discard packet remainder if any
|
||||||
|
if (!s_axis_tlast) begin
|
||||||
|
eth_state <= ST_DISCARD;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ST_RECV_CFG: begin
|
||||||
|
if (axis_hs) begin
|
||||||
|
// little endian packing
|
||||||
|
cfg_shift_eth[cfg_byte_cnt*8 +: 8] <= s_axis_tdata;
|
||||||
|
|
||||||
|
if (cfg_byte_cnt == 4'd15) begin
|
||||||
|
// this must be the final payload byte
|
||||||
|
if (s_axis_tlast) begin
|
||||||
|
cfg_bus_eth <= {s_axis_tdata, cfg_shift_eth[119:0]};
|
||||||
|
cfg_req_toggle_dac_eth <= ~cfg_req_toggle_dac_eth;
|
||||||
|
cfg_req_toggle_adc_eth <= ~cfg_req_toggle_adc_eth;
|
||||||
|
cfg_wait_dac_ack <= 1'b1;
|
||||||
|
cfg_wait_adc_ack <= 1'b1;
|
||||||
|
eth_state <= ST_WAIT_CFG_ACK;
|
||||||
|
end else begin
|
||||||
|
// too many bytes in packet
|
||||||
|
eth_state <= ST_DISCARD;
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
|
// early tlast means packet too short!!
|
||||||
|
if (s_axis_tlast) begin
|
||||||
|
eth_state <= ST_IDLE;
|
||||||
|
end else begin
|
||||||
|
cfg_byte_cnt <= cfg_byte_cnt + 4'd1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ST_WAIT_CFG_ACK: begin
|
||||||
|
// any incoming packet while waiting ack is discarded
|
||||||
|
if (cfg_ack_pulse_dac_eth || cfg_ack_pulse_adc_eth) begin
|
||||||
|
if ((~cfg_wait_dac_ack || cfg_ack_pulse_dac_eth) &&
|
||||||
|
(~cfg_wait_adc_ack || cfg_ack_pulse_adc_eth)) begin
|
||||||
|
eth_state <= ST_IDLE;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (axis_hs && !s_axis_tlast) begin
|
||||||
|
eth_state <= ST_DISCARD;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ST_DISCARD: begin
|
||||||
|
if (axis_hs && s_axis_tlast) begin
|
||||||
|
eth_state <= ST_IDLE;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
default: begin
|
||||||
|
eth_state <= ST_IDLE;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// ETH -> DAC: start/reset event sync
|
||||||
(* ASYNC_REG = "TRUE" *) logic start_meta_dac, start_sync_dac;
|
(* ASYNC_REG = "TRUE" *) logic start_meta_dac, start_sync_dac;
|
||||||
logic start_sync_dac_d;
|
logic start_sync_dac_d;
|
||||||
(* ASYNC_REG = "TRUE" *) logic rst_meta_dac, rst_sync_dac;
|
(* ASYNC_REG = "TRUE" *) logic rst_meta_dac, rst_sync_dac;
|
||||||
@@ -225,11 +353,11 @@ module control #(
|
|||||||
dac_start <= 1'b0;
|
dac_start <= 1'b0;
|
||||||
dac_rst <= 1'b0;
|
dac_rst <= 1'b0;
|
||||||
end else begin
|
end else begin
|
||||||
start_meta_dac <= start_toggle;
|
start_meta_dac <= start_toggle_eth;
|
||||||
start_sync_dac <= start_meta_dac;
|
start_sync_dac <= start_meta_dac;
|
||||||
start_sync_dac_d <= start_sync_dac;
|
start_sync_dac_d <= start_sync_dac;
|
||||||
|
|
||||||
rst_meta_dac <= rst_toggle;
|
rst_meta_dac <= rst_toggle_eth;
|
||||||
rst_sync_dac <= rst_meta_dac;
|
rst_sync_dac <= rst_meta_dac;
|
||||||
rst_sync_dac_d <= rst_sync_dac;
|
rst_sync_dac_d <= rst_sync_dac;
|
||||||
|
|
||||||
@@ -238,7 +366,7 @@ module control #(
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
// cntrl -> ADC: start/reset event sync
|
// ETH -> ADC: start/reset event sync
|
||||||
(* ASYNC_REG = "TRUE" *) logic start_meta_adc, start_sync_adc;
|
(* ASYNC_REG = "TRUE" *) logic start_meta_adc, start_sync_adc;
|
||||||
logic start_sync_adc_d;
|
logic start_sync_adc_d;
|
||||||
(* ASYNC_REG = "TRUE" *) logic rst_meta_adc, rst_sync_adc;
|
(* ASYNC_REG = "TRUE" *) logic rst_meta_adc, rst_sync_adc;
|
||||||
@@ -260,11 +388,11 @@ module control #(
|
|||||||
adc_start <= 1'b0;
|
adc_start <= 1'b0;
|
||||||
adc_rst <= 1'b0;
|
adc_rst <= 1'b0;
|
||||||
end else begin
|
end else begin
|
||||||
start_meta_adc <= start_toggle;
|
start_meta_adc <= start_toggle_eth;
|
||||||
start_sync_adc <= start_meta_adc;
|
start_sync_adc <= start_meta_adc;
|
||||||
start_sync_adc_d <= start_sync_adc;
|
start_sync_adc_d <= start_sync_adc;
|
||||||
|
|
||||||
rst_meta_adc <= rst_toggle;
|
rst_meta_adc <= rst_toggle_eth;
|
||||||
rst_sync_adc <= rst_meta_adc;
|
rst_sync_adc <= rst_meta_adc;
|
||||||
rst_sync_adc_d <= rst_sync_adc;
|
rst_sync_adc_d <= rst_sync_adc;
|
||||||
|
|
||||||
@@ -273,8 +401,8 @@ module control #(
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
// contrl -> DAC config CDC
|
// ETH -> DAC config CDC
|
||||||
// cfg_bus is kept stable in contrl domain until DAC and ADC both ACK.
|
// cfg_bus_eth is kept stable in ETH domain until DAC and ADC both ACK.
|
||||||
(* ASYNC_REG = "TRUE" *) logic cfg_req_meta_dac, cfg_req_sync_dac;
|
(* ASYNC_REG = "TRUE" *) logic cfg_req_meta_dac, cfg_req_sync_dac;
|
||||||
logic cfg_req_sync_dac_d;
|
logic cfg_req_sync_dac_d;
|
||||||
wire cfg_req_pulse_dac = cfg_req_sync_dac ^ cfg_req_sync_dac_d;
|
wire cfg_req_pulse_dac = cfg_req_sync_dac ^ cfg_req_sync_dac_d;
|
||||||
@@ -291,22 +419,22 @@ module control #(
|
|||||||
dac_pulse_num <= '0;
|
dac_pulse_num <= '0;
|
||||||
dac_pulse_height <= '0;
|
dac_pulse_height <= '0;
|
||||||
end else begin
|
end else begin
|
||||||
cfg_req_meta_dac <= cfg_req_toggle_dac;
|
cfg_req_meta_dac <= cfg_req_toggle_dac_eth;
|
||||||
cfg_req_sync_dac <= cfg_req_meta_dac;
|
cfg_req_sync_dac <= cfg_req_meta_dac;
|
||||||
cfg_req_sync_dac_d <= cfg_req_sync_dac;
|
cfg_req_sync_dac_d <= cfg_req_sync_dac;
|
||||||
|
|
||||||
if (cfg_req_pulse_dac) begin
|
if (cfg_req_pulse_dac) begin
|
||||||
dac_pulse_width <= cfg_bus[31:0];
|
dac_pulse_width <= cfg_bus_eth[31:0];
|
||||||
dac_pulse_period <= cfg_bus[63:32];
|
dac_pulse_period <= cfg_bus_eth[63:32];
|
||||||
dac_pulse_num <= cfg_bus[79:64];
|
dac_pulse_num <= cfg_bus_eth[79:64];
|
||||||
dac_pulse_height <= cfg_bus[80 +: DAC_DATA_WIDTH];
|
dac_pulse_height <= cfg_bus_eth[80 +: DAC_DATA_WIDTH];
|
||||||
|
|
||||||
cfg_ack_toggle_dac <= ~cfg_ack_toggle_dac;
|
cfg_ack_toggle_dac <= ~cfg_ack_toggle_dac;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
// cntrl -> ADC config CDC
|
// ETH -> ADC config CDC
|
||||||
logic cfg_req_meta_adc, cfg_req_sync_adc, cfg_req_sync_adc_d;
|
logic cfg_req_meta_adc, cfg_req_sync_adc, cfg_req_sync_adc_d;
|
||||||
wire cfg_req_pulse_adc = cfg_req_sync_adc ^ cfg_req_sync_adc_d;
|
wire cfg_req_pulse_adc = cfg_req_sync_adc ^ cfg_req_sync_adc_d;
|
||||||
|
|
||||||
@@ -319,16 +447,14 @@ module control #(
|
|||||||
|
|
||||||
adc_pulse_period <= '0;
|
adc_pulse_period <= '0;
|
||||||
adc_pulse_num <= '0;
|
adc_pulse_num <= '0;
|
||||||
adc_window_size <= '0;
|
|
||||||
end else begin
|
end else begin
|
||||||
cfg_req_meta_adc <= cfg_req_toggle_adc;
|
cfg_req_meta_adc <= cfg_req_toggle_adc_eth;
|
||||||
cfg_req_sync_adc <= cfg_req_meta_adc;
|
cfg_req_sync_adc <= cfg_req_meta_adc;
|
||||||
cfg_req_sync_adc_d <= cfg_req_sync_adc;
|
cfg_req_sync_adc_d <= cfg_req_sync_adc;
|
||||||
|
|
||||||
if (cfg_req_pulse_adc) begin
|
if (cfg_req_pulse_adc) begin
|
||||||
adc_pulse_period <= cfg_bus[127:96];
|
adc_pulse_period <= cfg_bus_eth[127:96];
|
||||||
adc_pulse_num <= cfg_bus[79:64];
|
adc_pulse_num <= cfg_bus_eth[79:64];
|
||||||
adc_window_size <= cfg_bus[159:128];
|
|
||||||
|
|
||||||
cfg_ack_toggle_adc <= ~cfg_ack_toggle_adc;
|
cfg_ack_toggle_adc <= ~cfg_ack_toggle_adc;
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,221 +0,0 @@
|
|||||||
import dma_reg_pkg::*;
|
|
||||||
|
|
||||||
module controller_wrapper_axil #(
|
|
||||||
|
|
||||||
parameter int unsigned ADDR_W = 16,
|
|
||||||
parameter int unsigned DATA_W = 32,
|
|
||||||
parameter int unsigned USER_W = 1,
|
|
||||||
|
|
||||||
parameter int unsigned DAC_DATA_WIDTH = 12
|
|
||||||
)
|
|
||||||
(
|
|
||||||
input logic ctrl_clk,
|
|
||||||
input logic dac_clk_in,
|
|
||||||
input logic adc_clk_in,
|
|
||||||
input logic rst_n,
|
|
||||||
axi4l_if.slave s_axil,
|
|
||||||
|
|
||||||
// adc_clk_in domain
|
|
||||||
input logic finish,
|
|
||||||
output logic [31:0] adc_window_size,
|
|
||||||
|
|
||||||
// dac_clk_in domain outputs
|
|
||||||
output logic [31:0] dac_pulse_width,
|
|
||||||
output logic [31:0] dac_pulse_period,
|
|
||||||
output logic [DAC_DATA_WIDTH-1:0] dac_pulse_height,
|
|
||||||
output logic [15:0] dac_pulse_num,
|
|
||||||
|
|
||||||
// adc_clk_in domain outputs
|
|
||||||
output logic [31:0] adc_pulse_period,
|
|
||||||
output logic [15:0] adc_pulse_num,
|
|
||||||
|
|
||||||
// pulse outputs
|
|
||||||
output logic dac_start,
|
|
||||||
output logic adc_start,
|
|
||||||
output logic dac_rst,
|
|
||||||
output logic adc_rst,
|
|
||||||
|
|
||||||
// AXIS DMA
|
|
||||||
axis_if.slave s_axis_status_read,
|
|
||||||
axis_if.slave s_axis_status_write,
|
|
||||||
|
|
||||||
axis_if.master m_axis_desc_read,
|
|
||||||
axis_if.master m_axis_desc_write
|
|
||||||
);
|
|
||||||
|
|
||||||
logic start, rst_soft, send_desc_read, send_desc_write, take_status_read, take_status_write, cfg_bus_valid, busy;
|
|
||||||
logic [31:0] pulse_width, pulse_period, pulse_num, pulse_height_raw, pulse_period_ADC, window_size;
|
|
||||||
logic [7:0] error_code;
|
|
||||||
logic [31:0] desc_read_addr, desc_read_len, desc_read_config, status_read;
|
|
||||||
logic [31:0] desc_write_addr, desc_write_len_and_tag, status_write_len, status_write_config;
|
|
||||||
|
|
||||||
logic desc_read_dma_busy, desc_write_dma_busy, status_read_dma_busy, status_write_dma_busy;
|
|
||||||
logic desc_read_dma_hs, desc_write_dma_hs, status_read_dma_hs, status_write_dma_hs;
|
|
||||||
|
|
||||||
axi4l_reg_map_controller #(
|
|
||||||
.ADDR_W(ADDR_W),
|
|
||||||
.DATA_W(DATA_W),
|
|
||||||
.USER_W(USER_W)
|
|
||||||
) axi4l_reg_map_controller_inst (
|
|
||||||
.clk(ctrl_clk),
|
|
||||||
.rst_n(rst_n),
|
|
||||||
.s_axil(s_axil),
|
|
||||||
// CONTROLLER ADC/ DAC
|
|
||||||
.start_o(start),
|
|
||||||
.cfg_bus_valid_o(cfg_bus_valid),
|
|
||||||
|
|
||||||
.pulse_width_o(pulse_width),
|
|
||||||
.pulse_period_o(pulse_period),
|
|
||||||
.pulse_num_o(pulse_num),
|
|
||||||
.pulse_height_raw_o(pulse_height_raw),
|
|
||||||
.pulse_period_ADC_o(pulse_period_ADC),
|
|
||||||
.window_size_o(window_size),
|
|
||||||
|
|
||||||
.rst_soft_o(rst_soft),
|
|
||||||
.busy_i(busy),
|
|
||||||
.error_code_i(error_code),
|
|
||||||
|
|
||||||
// CONTROLLER DMA
|
|
||||||
.send_desc_read_o(send_desc_read),
|
|
||||||
.send_desc_write_o(send_desc_write),
|
|
||||||
.take_status_read_o(take_status_read),
|
|
||||||
.take_status_write_o(take_status_write),
|
|
||||||
|
|
||||||
.desc_read_addr_o(desc_read_addr),
|
|
||||||
.desc_read_len_o(desc_read_len),
|
|
||||||
.desc_read_config_o(desc_read_config),
|
|
||||||
|
|
||||||
.status_read_i(status_read),
|
|
||||||
|
|
||||||
.desc_write_addr_o(desc_write_addr),
|
|
||||||
.desc_write_len_and_tag_o(desc_write_len_and_tag),
|
|
||||||
|
|
||||||
.status_write_len_i(status_write_len),
|
|
||||||
.status_write_config_i(status_write_config),
|
|
||||||
|
|
||||||
.desc_read_dma_busy_i(desc_read_dma_busy),
|
|
||||||
.desc_write_dma_busy_i(desc_write_dma_busy),
|
|
||||||
.status_read_dma_busy_i(status_read_dma_busy),
|
|
||||||
.status_write_dma_busy_i(status_write_dma_busy),
|
|
||||||
|
|
||||||
.desc_read_dma_hs_i(desc_read_dma_hs),
|
|
||||||
.desc_write_dma_hs_i(desc_write_dma_hs),
|
|
||||||
.status_read_dma_hs_i(status_read_dma_hs),
|
|
||||||
.status_write_dma_hs_i(status_write_dma_hs)
|
|
||||||
);
|
|
||||||
|
|
||||||
// CONTROLLER DAC ADC
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// Field layout inside cfg_bus:
|
|
||||||
// [31:0] pulse_width
|
|
||||||
// [63:32] pulse_period
|
|
||||||
// [79:64] pulse_num
|
|
||||||
// [95:80] pulse_height_raw[15:0]
|
|
||||||
// [127:96] pulse_period_ADC
|
|
||||||
// [159:128] window_size
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
(* MARK_DEBUG="true" *) logic [159:0] cfg_bus;
|
|
||||||
assign cfg_bus = {window_size, pulse_period_ADC, pulse_height_raw[15:0], pulse_num[15:0], pulse_period, pulse_width};
|
|
||||||
|
|
||||||
control #(
|
|
||||||
.DAC_DATA_WIDTH(DAC_DATA_WIDTH)
|
|
||||||
)
|
|
||||||
controller (
|
|
||||||
.ctrl_clk(ctrl_clk),
|
|
||||||
.dac_clk_in(dac_clk_in),
|
|
||||||
.adc_clk_in(adc_clk_in),
|
|
||||||
.rst_n(rst_n),
|
|
||||||
.rst_soft(rst_soft),
|
|
||||||
.finish(finish),
|
|
||||||
.cfg_bus_input(cfg_bus),
|
|
||||||
.cfg_bus_valid(cfg_bus_valid),
|
|
||||||
.start(start),
|
|
||||||
|
|
||||||
.busy(busy),
|
|
||||||
|
|
||||||
.dac_pulse_width(dac_pulse_width),
|
|
||||||
.dac_pulse_period(dac_pulse_period),
|
|
||||||
.dac_pulse_height(dac_pulse_height),
|
|
||||||
.dac_pulse_num(dac_pulse_num),
|
|
||||||
.adc_pulse_period(adc_pulse_period),
|
|
||||||
.adc_pulse_num(adc_pulse_num),
|
|
||||||
.adc_window_size(adc_window_size),
|
|
||||||
.dac_start(dac_start),
|
|
||||||
.adc_start(adc_start),
|
|
||||||
.dac_rst(dac_rst),
|
|
||||||
.adc_rst(adc_rst)
|
|
||||||
);
|
|
||||||
|
|
||||||
// CONTROLLER DMA
|
|
||||||
|
|
||||||
dma_read_desc_t desc_read_cmd, desc_read_cmd_out;
|
|
||||||
assign desc_read_cmd.addr = desc_read_addr;
|
|
||||||
assign desc_read_cmd.len = desc_read_len;
|
|
||||||
assign desc_read_cmd.tag = desc_read_config[TAG_WIDTH-1:0];
|
|
||||||
assign desc_read_cmd.id = desc_read_config[TAG_WIDTH +: AXIS_ID_WIDTH];
|
|
||||||
assign desc_read_cmd.dest = desc_read_config[TAG_WIDTH+AXIS_ID_WIDTH +: AXIS_DEST_WIDTH];
|
|
||||||
assign desc_read_cmd.user = desc_read_config[TAG_WIDTH+AXIS_ID_WIDTH+AXIS_DEST_WIDTH +: AXIS_USER_WIDTH];
|
|
||||||
|
|
||||||
dma_write_desc_t desc_write_cmd, desc_write_cmd_out;
|
|
||||||
assign desc_write_cmd.addr = desc_write_addr;
|
|
||||||
assign desc_write_cmd.len = desc_write_len_and_tag[LEN_WIDTH-1:0];
|
|
||||||
assign desc_write_cmd.tag = desc_write_len_and_tag[LEN_WIDTH +: TAG_WIDTH];
|
|
||||||
|
|
||||||
dma_read_status_t status_read_cmd, status_read_cmd_in;
|
|
||||||
assign status_read = { status_read_cmd.error, status_read_cmd.tag};
|
|
||||||
|
|
||||||
dma_write_status_t status_write_cmd, status_write_cmd_in;
|
|
||||||
assign status_write_len = status_write_cmd.len;
|
|
||||||
assign status_write_config = { status_write_cmd.error, status_write_cmd.user,
|
|
||||||
status_write_cmd.dest, status_write_cmd.id, status_write_cmd.tag};
|
|
||||||
|
|
||||||
dma_controller dma_controller_inst
|
|
||||||
(
|
|
||||||
.dma_clk(ctrl_clk),
|
|
||||||
.rst_n(rst_n),
|
|
||||||
|
|
||||||
.send_desc_read(send_desc_read),
|
|
||||||
.send_desc_write(send_desc_write),
|
|
||||||
.take_status_read(take_status_read),
|
|
||||||
.take_status_write(take_status_write),
|
|
||||||
|
|
||||||
.desc_read_cmd(desc_read_cmd),
|
|
||||||
.desc_write_cmd(desc_write_cmd),
|
|
||||||
.status_read_cmd(status_read_cmd),
|
|
||||||
.status_write_cmd(status_write_cmd),
|
|
||||||
|
|
||||||
.desc_read_cmd_out(desc_read_cmd_out),
|
|
||||||
.desc_write_cmd_out(desc_write_cmd_out),
|
|
||||||
.status_read_cmd_in(status_read_cmd_in),
|
|
||||||
.status_write_cmd_in(status_write_cmd_in),
|
|
||||||
|
|
||||||
.ready_desc_read(m_axis_desc_read.resp.ready),
|
|
||||||
.ready_desc_write(m_axis_desc_write.resp.ready),
|
|
||||||
.ready_status_read(s_axis_status_read.resp.ready),
|
|
||||||
.ready_status_write(s_axis_status_write.resp.ready),
|
|
||||||
|
|
||||||
.valid_desc_read(m_axis_desc_read.req.t.valid),
|
|
||||||
.valid_desc_write(m_axis_desc_write.req.t.valid),
|
|
||||||
.valid_status_read(s_axis_status_read.req.t.valid),
|
|
||||||
.valid_status_write(s_axis_status_write.req.t.valid),
|
|
||||||
|
|
||||||
.desc_read_dma_busy(desc_read_dma_busy),
|
|
||||||
.desc_write_dma_busy(desc_write_dma_busy),
|
|
||||||
.status_read_dma_busy(status_read_dma_busy),
|
|
||||||
.status_write_dma_busy(status_write_dma_busy),
|
|
||||||
|
|
||||||
.desc_read_dma_hs(desc_read_dma_hs),
|
|
||||||
.desc_write_dma_hs(desc_write_dma_hs),
|
|
||||||
.status_read_dma_hs(status_read_dma_hs),
|
|
||||||
.status_write_dma_hs(status_write_dma_hs)
|
|
||||||
);
|
|
||||||
|
|
||||||
axis_defaults_master defaults_rd (.axis(m_axis_desc_read));
|
|
||||||
axis_defaults_master defaults_wr (.axis(m_axis_desc_write));
|
|
||||||
|
|
||||||
assign m_axis_desc_read.req.t.data = desc_read_cmd_out;
|
|
||||||
assign m_axis_desc_write.req.t.data = desc_write_cmd_out;
|
|
||||||
assign status_read_cmd_in = s_axis_status_read.req.t.data;
|
|
||||||
assign status_write_cmd_in = s_axis_status_write.req.t.data;
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
import dma_reg_pkg::*;
|
|
||||||
|
|
||||||
module dma_controller
|
|
||||||
(
|
|
||||||
input dma_clk,
|
|
||||||
input rst_n,
|
|
||||||
input logic send_desc_read,
|
|
||||||
input logic send_desc_write,
|
|
||||||
input logic take_status_read,
|
|
||||||
input logic take_status_write,
|
|
||||||
|
|
||||||
input logic ready_desc_read,
|
|
||||||
input logic ready_desc_write,
|
|
||||||
|
|
||||||
output logic ready_status_read,
|
|
||||||
output logic ready_status_write,
|
|
||||||
|
|
||||||
input dma_read_desc_t desc_read_cmd,
|
|
||||||
input dma_write_desc_t desc_write_cmd,
|
|
||||||
|
|
||||||
output dma_read_status_t status_read_cmd,
|
|
||||||
output dma_write_status_t status_write_cmd,
|
|
||||||
|
|
||||||
input dma_read_status_t status_read_cmd_in,
|
|
||||||
input dma_write_status_t status_write_cmd_in,
|
|
||||||
|
|
||||||
output logic desc_read_dma_busy,
|
|
||||||
output logic desc_write_dma_busy,
|
|
||||||
output logic status_read_dma_busy,
|
|
||||||
output logic status_write_dma_busy,
|
|
||||||
|
|
||||||
output logic desc_read_dma_hs,
|
|
||||||
output logic desc_write_dma_hs,
|
|
||||||
output logic status_read_dma_hs,
|
|
||||||
output logic status_write_dma_hs,
|
|
||||||
|
|
||||||
output logic valid_desc_read,
|
|
||||||
output logic valid_desc_write,
|
|
||||||
|
|
||||||
input logic valid_status_read,
|
|
||||||
input logic valid_status_write,
|
|
||||||
|
|
||||||
output dma_read_desc_t desc_read_cmd_out,
|
|
||||||
output dma_write_desc_t desc_write_cmd_out
|
|
||||||
);
|
|
||||||
|
|
||||||
shaper_axis_desc
|
|
||||||
#(
|
|
||||||
.DATA_WIDTH($bits(dma_read_desc_t))
|
|
||||||
) shaper_axis_desc_read
|
|
||||||
(
|
|
||||||
.clk(dma_clk),
|
|
||||||
.rst_n(rst_n),
|
|
||||||
.data_in(desc_read_cmd),
|
|
||||||
.send(send_desc_read),
|
|
||||||
.ready(ready_desc_read),
|
|
||||||
.busy(desc_read_dma_busy),
|
|
||||||
.handshake(desc_read_dma_hs),
|
|
||||||
.data_out(desc_read_cmd_out),
|
|
||||||
.valid(valid_desc_read)
|
|
||||||
);
|
|
||||||
|
|
||||||
shaper_axis_desc
|
|
||||||
#(
|
|
||||||
.DATA_WIDTH($bits(dma_write_desc_t))
|
|
||||||
) shaper_axis_desc_write
|
|
||||||
(
|
|
||||||
.clk(dma_clk),
|
|
||||||
.rst_n(rst_n),
|
|
||||||
.data_in(desc_write_cmd),
|
|
||||||
.send(send_desc_write),
|
|
||||||
.ready(ready_desc_write),
|
|
||||||
.busy(desc_write_dma_busy),
|
|
||||||
.handshake(desc_write_dma_hs),
|
|
||||||
.data_out(desc_write_cmd_out),
|
|
||||||
.valid(valid_desc_write)
|
|
||||||
);
|
|
||||||
|
|
||||||
shaper_axis_status
|
|
||||||
#(
|
|
||||||
.DATA_WIDTH($bits(dma_read_status_t))
|
|
||||||
) shaper_axis_status_read
|
|
||||||
(
|
|
||||||
.clk(dma_clk),
|
|
||||||
.rst_n(rst_n),
|
|
||||||
.data_in(status_read_cmd_in),
|
|
||||||
.take(take_status_read),
|
|
||||||
.valid(valid_status_read),
|
|
||||||
.ready(ready_status_read),
|
|
||||||
.busy(status_read_dma_busy),
|
|
||||||
.handshake(status_read_dma_hs),
|
|
||||||
.data_out(status_read_cmd)
|
|
||||||
);
|
|
||||||
|
|
||||||
shaper_axis_status
|
|
||||||
#(
|
|
||||||
.DATA_WIDTH($bits(dma_write_status_t))
|
|
||||||
) shaper_axis_status_write
|
|
||||||
(
|
|
||||||
.clk(dma_clk),
|
|
||||||
.rst_n(rst_n),
|
|
||||||
.data_in(status_write_cmd_in),
|
|
||||||
.take(take_status_write),
|
|
||||||
.valid(valid_status_write),
|
|
||||||
.ready(ready_status_write),
|
|
||||||
.busy(status_write_dma_busy),
|
|
||||||
.handshake(status_write_dma_hs),
|
|
||||||
.data_out(status_write_cmd)
|
|
||||||
);
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
package dma_reg_pkg;
|
|
||||||
parameter int unsigned AXI_ADDR_WIDTH = 16;
|
|
||||||
parameter int unsigned LEN_WIDTH = 20;
|
|
||||||
parameter int unsigned TAG_WIDTH = 8;
|
|
||||||
parameter int unsigned AXIS_ID_WIDTH = 8;
|
|
||||||
parameter int unsigned AXIS_DEST_WIDTH = 8;
|
|
||||||
parameter int unsigned AXIS_USER_WIDTH = 1;
|
|
||||||
|
|
||||||
typedef struct packed {
|
|
||||||
logic [AXIS_USER_WIDTH-1:0] user;
|
|
||||||
logic [AXIS_DEST_WIDTH-1:0] dest;
|
|
||||||
logic [AXIS_ID_WIDTH-1:0] id;
|
|
||||||
logic [TAG_WIDTH-1:0] tag;
|
|
||||||
logic [LEN_WIDTH-1:0] len;
|
|
||||||
logic [AXI_ADDR_WIDTH-1:0] addr;
|
|
||||||
|
|
||||||
} dma_read_desc_t;
|
|
||||||
|
|
||||||
typedef struct packed {
|
|
||||||
logic [TAG_WIDTH-1:0] tag;
|
|
||||||
logic [LEN_WIDTH-1:0] len;
|
|
||||||
logic [AXI_ADDR_WIDTH-1:0] addr;
|
|
||||||
|
|
||||||
} dma_write_desc_t;
|
|
||||||
|
|
||||||
typedef struct packed {
|
|
||||||
logic [3:0] error;
|
|
||||||
logic [TAG_WIDTH-1:0] tag;
|
|
||||||
|
|
||||||
} dma_read_status_t;
|
|
||||||
|
|
||||||
typedef struct packed {
|
|
||||||
logic [3:0] error;
|
|
||||||
logic [AXIS_USER_WIDTH-1:0] user;
|
|
||||||
logic [AXIS_DEST_WIDTH-1:0] dest;
|
|
||||||
logic [AXIS_ID_WIDTH-1:0] id;
|
|
||||||
logic [TAG_WIDTH-1:0] tag;
|
|
||||||
logic [LEN_WIDTH-1:0] len;
|
|
||||||
|
|
||||||
} dma_write_status_t;
|
|
||||||
|
|
||||||
endpackage
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
module shaper_axis_desc #(
|
|
||||||
parameter DATA_WIDTH = 128
|
|
||||||
) (
|
|
||||||
input clk,
|
|
||||||
input rst_n,
|
|
||||||
input logic [DATA_WIDTH-1:0] data_in,
|
|
||||||
input logic send,
|
|
||||||
input logic ready,
|
|
||||||
|
|
||||||
output logic busy,
|
|
||||||
output logic handshake,
|
|
||||||
output logic [DATA_WIDTH-1:0] data_out,
|
|
||||||
output logic valid
|
|
||||||
);
|
|
||||||
|
|
||||||
typedef enum logic [0:0] {
|
|
||||||
IDLE,
|
|
||||||
WAIT_READY
|
|
||||||
} wr_state;
|
|
||||||
|
|
||||||
wr_state state;
|
|
||||||
|
|
||||||
always @(posedge clk) begin
|
|
||||||
if (!rst_n) begin
|
|
||||||
state <= IDLE;
|
|
||||||
busy <= 1'b0;
|
|
||||||
handshake <= 1'b0;
|
|
||||||
data_out <= 1'b0;
|
|
||||||
valid <= 1'b0;
|
|
||||||
end else begin
|
|
||||||
case (state)
|
|
||||||
IDLE: begin
|
|
||||||
handshake <= 1'b0;
|
|
||||||
if (send) begin
|
|
||||||
valid <= 1'b1;
|
|
||||||
data_out <= data_in;
|
|
||||||
busy <= 1'b1;
|
|
||||||
state <= WAIT_READY;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
WAIT_READY: begin
|
|
||||||
if (ready) begin
|
|
||||||
valid <= 1'b0;
|
|
||||||
handshake <= 1'b1;
|
|
||||||
busy <= 1'b0;
|
|
||||||
state <= IDLE;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
default: state <= IDLE;
|
|
||||||
endcase
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
module shaper_axis_status #(
|
|
||||||
parameter int unsigned DATA_WIDTH = 128
|
|
||||||
)(
|
|
||||||
input logic clk,
|
|
||||||
input logic rst_n,
|
|
||||||
|
|
||||||
input logic [DATA_WIDTH-1:0] data_in,
|
|
||||||
input logic take,
|
|
||||||
input logic valid,
|
|
||||||
output logic ready,
|
|
||||||
|
|
||||||
output logic busy,
|
|
||||||
output logic handshake,
|
|
||||||
output logic [DATA_WIDTH-1:0] data_out
|
|
||||||
);
|
|
||||||
|
|
||||||
typedef enum logic [0:0] {
|
|
||||||
IDLE,
|
|
||||||
WAIT_TAKE
|
|
||||||
} wr_state;
|
|
||||||
|
|
||||||
wr_state state;
|
|
||||||
|
|
||||||
logic [31:0] data_reg;
|
|
||||||
|
|
||||||
always @(posedge clk) begin
|
|
||||||
if (!rst_n) begin
|
|
||||||
state <= IDLE;
|
|
||||||
ready <= 1'b0;
|
|
||||||
busy <= 1'b0;
|
|
||||||
handshake <= 1'b0;
|
|
||||||
data_out <= '0;
|
|
||||||
data_reg <= '0;
|
|
||||||
end else begin
|
|
||||||
case (state)
|
|
||||||
IDLE: begin
|
|
||||||
ready <= 1'b1;
|
|
||||||
if (valid) begin
|
|
||||||
busy <= 1'b0;
|
|
||||||
data_reg <= data_in;
|
|
||||||
handshake <= 1'b1;
|
|
||||||
state <= WAIT_TAKE;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
WAIT_TAKE: begin
|
|
||||||
if (take) begin
|
|
||||||
data_out <= data_reg;
|
|
||||||
ready <= 1'b0;
|
|
||||||
handshake <= 1'b0;
|
|
||||||
busy <= 1'b1;
|
|
||||||
state <= IDLE;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
endcase
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
@@ -1,40 +1,52 @@
|
|||||||
TOPLEVEL_LANG = verilog
|
# SPDX-License-Identifier: MIT
|
||||||
SIM ?= verilator
|
#
|
||||||
|
# Copyright (c) 2025 FPGA Ninja, LLC
|
||||||
|
#
|
||||||
|
# Authors:
|
||||||
|
# - Alex Forencich
|
||||||
|
#
|
||||||
|
|
||||||
PWD := $(shell pwd)
|
# FPGA settings
|
||||||
|
FPGA_PART = xc7a35tfgg484-1
|
||||||
|
FPGA_TOP = control
|
||||||
|
FPGA_ARCH = artix7
|
||||||
|
|
||||||
RTL_DIR = $(PWD)/../src
|
RTL_DIR = ../src
|
||||||
LIBS_DIR = $(PWD)/../../../external/rtl_libs
|
|
||||||
|
|
||||||
VERILOG_SOURCES += $(LIBS_DIR)/axi/rtl/axi_pkg.sv
|
|
||||||
VERILOG_SOURCES += $(LIBS_DIR)/axi/rtl/axi_if.sv
|
|
||||||
VERILOG_SOURCES += $(LIBS_DIR)/axi/rtl/axi4l_flat_to_if.sv
|
|
||||||
VERILOG_SOURCES += $(LIBS_DIR)/axi/rtl/axi4l_if_to_flat.sv
|
|
||||||
VERILOG_SOURCES += $(LIBS_DIR)/axi/axi_reg/axi4l_reg_map.sv
|
|
||||||
VERILOG_SOURCES += $(RTL_DIR)/controller.sv
|
|
||||||
VERILOG_SOURCES += $(RTL_DIR)/dma_controller.sv
|
|
||||||
VERILOG_SOURCES += $(RTL_DIR)/shaper_axis_desc.sv
|
|
||||||
VERILOG_SOURCES += $(RTL_DIR)/shaper_axis_status.sv
|
|
||||||
VERILOG_SOURCES += $(RTL_DIR)/controller_wrapper_axil.sv
|
|
||||||
VERILOG_SOURCES += $(RTL_DIR)/axi4l_reg_map_controller_pkg.sv
|
|
||||||
VERILOG_SOURCES += $(RTL_DIR)/axi4l_reg_map_controller.sv
|
|
||||||
VERILOG_SOURCES += $(PWD)/tb_controller_wrapper_axil.sv
|
|
||||||
|
|
||||||
TOPLEVEL = tb_controller_wrapper_axil
|
|
||||||
MODULE = test_controller
|
|
||||||
|
|
||||||
|
|
||||||
ifeq ($(SIM),verilator)
|
include ../../../scripts/vivado.mk
|
||||||
EXTRA_ARGS += --trace --trace-structs
|
|
||||||
EXTRA_ARGS += -I$(LIBS_DIR)/axi/rtl/
|
SYN_FILES += $(sort $(shell find ../src -type f \( -name '*.v' -o -name '*.sv' \)))
|
||||||
COMPILE_ARGS += -Wno-fatal
|
|
||||||
COMPILE_ARGS += -I$(LIBS_DIR)/axi/rtl/
|
XCI_FILES = $(sort $(shell find ../src -type f -name '*.xci'))
|
||||||
EXTRA_ARGS += --trace
|
|
||||||
EXTRA_ARGS += --trace-structs
|
XDC_FILES += ../../../constraints/ax7a035b.xdc
|
||||||
EXTRA_ARGS += --public-flat-rw
|
XDC_FILES += test_timing.xdc
|
||||||
EXTRA_ARGS += -Wno-fatal
|
|
||||||
EXTRA_ARGS += --timing
|
SYN_FILES += controller_tb.sv
|
||||||
endif
|
SIM_TOP = control_tb
|
||||||
|
|
||||||
|
|
||||||
include $(shell cocotb-config --makefiles)/Makefile.sim
|
program: $(PROJECT).bit
|
||||||
|
echo "open_hw_manager" > program.tcl
|
||||||
|
echo "connect_hw_server" >> program.tcl
|
||||||
|
echo "open_hw_target" >> program.tcl
|
||||||
|
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
|
||||||
|
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
|
||||||
|
echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl
|
||||||
|
echo "program_hw_devices [current_hw_device]" >> program.tcl
|
||||||
|
echo "exit" >> program.tcl
|
||||||
|
vivado -nojournal -nolog -mode batch -source program.tcl
|
||||||
|
|
||||||
|
$(PROJECT).mcs $(PROJECT).prm: $(PROJECT).bit
|
||||||
|
echo "write_cfgmem -force -format mcs -size 16 -interface SPIx4 -loadbit {up 0x0000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
|
||||||
|
echo "exit" >> generate_mcs.tcl
|
||||||
|
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
|
||||||
|
mkdir -p rev
|
||||||
|
COUNT=100; \
|
||||||
|
while [ -e rev/$*_rev$$COUNT.bit ]; \
|
||||||
|
do COUNT=$$((COUNT+1)); done; \
|
||||||
|
COUNT=$$((COUNT-1)); \
|
||||||
|
for x in .mcs .prm; \
|
||||||
|
do cp $*$$x rev/$*_rev$$COUNT$$x; \
|
||||||
|
echo "Output: rev/$*_rev$$COUNT$$x"; done;
|
||||||
|
|||||||
@@ -4,17 +4,72 @@ module tb_control;
|
|||||||
|
|
||||||
localparam int unsigned DAC_DATA_WIDTH = 12;
|
localparam int unsigned DAC_DATA_WIDTH = 12;
|
||||||
|
|
||||||
//------------------------------------------------------------
|
|
||||||
// Clocks / reset
|
// Clocks / reset
|
||||||
//------------------------------------------------------------
|
logic eth_clk_in;
|
||||||
logic ctrl_clk;
|
|
||||||
logic dac_clk_in;
|
logic dac_clk_in;
|
||||||
logic adc_clk_in;
|
logic adc_clk_in;
|
||||||
logic rst_n;
|
logic rst_n;
|
||||||
|
|
||||||
|
// axi stream (input)
|
||||||
|
logic [7:0] s_axis_tdata;
|
||||||
|
logic s_axis_tvalid;
|
||||||
|
logic s_axis_tready;
|
||||||
|
logic s_axis_tlast;
|
||||||
|
|
||||||
|
// ADC side input
|
||||||
|
logic finish;
|
||||||
|
|
||||||
|
// DUT outputs
|
||||||
|
logic [31:0] dac_pulse_width;
|
||||||
|
logic [31:0] dac_pulse_period;
|
||||||
|
logic [DAC_DATA_WIDTH-1:0] dac_pulse_height;
|
||||||
|
logic [15:0] dac_pulse_num;
|
||||||
|
|
||||||
|
logic [31:0] adc_pulse_period;
|
||||||
|
logic [15:0] adc_pulse_num;
|
||||||
|
|
||||||
|
logic dac_start;
|
||||||
|
logic adc_start;
|
||||||
|
logic dac_rst;
|
||||||
|
logic adc_rst;
|
||||||
|
|
||||||
|
|
||||||
|
// DUT
|
||||||
|
control #(
|
||||||
|
.DAC_DATA_WIDTH(DAC_DATA_WIDTH)
|
||||||
|
) dut (
|
||||||
|
.eth_clk_in (eth_clk_in),
|
||||||
|
.dac_clk_in (dac_clk_in),
|
||||||
|
.adc_clk_in (adc_clk_in),
|
||||||
|
.rst_n (rst_n),
|
||||||
|
|
||||||
|
.s_axis_tdata (s_axis_tdata),
|
||||||
|
.s_axis_tvalid (s_axis_tvalid),
|
||||||
|
.s_axis_tready (s_axis_tready),
|
||||||
|
.s_axis_tlast (s_axis_tlast),
|
||||||
|
|
||||||
|
.finish (finish),
|
||||||
|
|
||||||
|
.dac_pulse_width (dac_pulse_width),
|
||||||
|
.dac_pulse_period (dac_pulse_period),
|
||||||
|
.dac_pulse_height (dac_pulse_height),
|
||||||
|
.dac_pulse_num (dac_pulse_num),
|
||||||
|
|
||||||
|
.adc_pulse_period (adc_pulse_period),
|
||||||
|
.adc_pulse_num (adc_pulse_num),
|
||||||
|
|
||||||
|
.dac_start (dac_start),
|
||||||
|
.adc_start (adc_start),
|
||||||
|
.dac_rst (dac_rst),
|
||||||
|
.adc_rst (adc_rst)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Clock generation
|
||||||
initial begin
|
initial begin
|
||||||
ctrl_clk = 1'b0;
|
eth_clk_in = 1'b0;
|
||||||
forever #(1 * 4.000) ctrl_clk = ~ctrl_clk; // 125 MHz
|
forever #(1 * 4.000) eth_clk_in = ~eth_clk_in; // 125 MHz
|
||||||
end
|
end
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
@@ -27,81 +82,8 @@ module tb_control;
|
|||||||
forever #(1 * 7.692307692) adc_clk_in = ~adc_clk_in; // ~65 MHz
|
forever #(1 * 7.692307692) adc_clk_in = ~adc_clk_in; // ~65 MHz
|
||||||
end
|
end
|
||||||
|
|
||||||
//------------------------------------------------------------
|
|
||||||
// DUT inputs
|
|
||||||
//------------------------------------------------------------
|
|
||||||
|
|
||||||
logic rst_soft;
|
|
||||||
|
|
||||||
logic finish;
|
|
||||||
|
|
||||||
logic [159:0] cfg_bus_input;
|
|
||||||
logic cfg_bus_valid;
|
|
||||||
|
|
||||||
logic start;
|
|
||||||
|
|
||||||
//------------------------------------------------------------
|
|
||||||
// DUT outputs
|
|
||||||
//------------------------------------------------------------
|
|
||||||
|
|
||||||
logic busy;
|
|
||||||
|
|
||||||
logic [31:0] dac_pulse_width;
|
|
||||||
logic [31:0] dac_pulse_period;
|
|
||||||
logic [DAC_DATA_WIDTH-1:0] dac_pulse_height;
|
|
||||||
logic [15:0] dac_pulse_num;
|
|
||||||
|
|
||||||
logic [31:0] adc_pulse_period;
|
|
||||||
logic [15:0] adc_pulse_num;
|
|
||||||
logic [31:0] adc_window_size;
|
|
||||||
|
|
||||||
logic dac_start;
|
|
||||||
logic adc_start;
|
|
||||||
logic dac_rst;
|
|
||||||
logic adc_rst;
|
|
||||||
|
|
||||||
//------------------------------------------------------------
|
|
||||||
// DUT
|
|
||||||
//------------------------------------------------------------
|
|
||||||
|
|
||||||
control #(
|
|
||||||
.DAC_DATA_WIDTH(DAC_DATA_WIDTH)
|
|
||||||
) dut (
|
|
||||||
.ctrl_clk (ctrl_clk),
|
|
||||||
.dac_clk_in (dac_clk_in),
|
|
||||||
.adc_clk_in (adc_clk_in),
|
|
||||||
|
|
||||||
.rst_n (rst_n),
|
|
||||||
.rst_soft (rst_soft),
|
|
||||||
|
|
||||||
.finish (finish),
|
|
||||||
|
|
||||||
.cfg_bus_input (cfg_bus_input),
|
|
||||||
.cfg_bus_valid (cfg_bus_valid),
|
|
||||||
|
|
||||||
.start (start),
|
|
||||||
|
|
||||||
.busy (busy),
|
|
||||||
|
|
||||||
.dac_pulse_width (dac_pulse_width),
|
|
||||||
.dac_pulse_period (dac_pulse_period),
|
|
||||||
.dac_pulse_height (dac_pulse_height),
|
|
||||||
.dac_pulse_num (dac_pulse_num),
|
|
||||||
|
|
||||||
.adc_pulse_period (adc_pulse_period),
|
|
||||||
.adc_pulse_num (adc_pulse_num),
|
|
||||||
.adc_window_size (adc_window_size),
|
|
||||||
|
|
||||||
.dac_start (dac_start),
|
|
||||||
.adc_start (adc_start),
|
|
||||||
.dac_rst (dac_rst),
|
|
||||||
.adc_rst (adc_rst)
|
|
||||||
);
|
|
||||||
|
|
||||||
//------------------------------------------------------------
|
|
||||||
// pulse counters and monitors for testing
|
// pulse counters and monitors for testing
|
||||||
//------------------------------------------------------------
|
|
||||||
|
|
||||||
int dac_rst_count;
|
int dac_rst_count;
|
||||||
int adc_rst_count;
|
int adc_rst_count;
|
||||||
int dac_start_count;
|
int dac_start_count;
|
||||||
@@ -111,13 +93,9 @@ module tb_control;
|
|||||||
if (!rst_n) begin
|
if (!rst_n) begin
|
||||||
dac_rst_count <= 0;
|
dac_rst_count <= 0;
|
||||||
dac_start_count <= 0;
|
dac_start_count <= 0;
|
||||||
end
|
end else begin
|
||||||
else begin
|
if (dac_rst) dac_rst_count <= dac_rst_count + 1;
|
||||||
if (dac_rst)
|
if (dac_start) dac_start_count <= dac_start_count + 1;
|
||||||
dac_rst_count <= dac_rst_count + 1;
|
|
||||||
|
|
||||||
if (dac_start)
|
|
||||||
dac_start_count <= dac_start_count + 1;
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -125,46 +103,35 @@ module tb_control;
|
|||||||
if (!rst_n) begin
|
if (!rst_n) begin
|
||||||
adc_rst_count <= 0;
|
adc_rst_count <= 0;
|
||||||
adc_start_count <= 0;
|
adc_start_count <= 0;
|
||||||
end
|
end else begin
|
||||||
else begin
|
if (adc_rst) adc_rst_count <= adc_rst_count + 1;
|
||||||
if (adc_rst)
|
if (adc_start) adc_start_count <= adc_start_count + 1;
|
||||||
adc_rst_count <= adc_rst_count + 1;
|
|
||||||
|
|
||||||
if (adc_start)
|
|
||||||
adc_start_count <= adc_start_count + 1;
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
//------------------------------------------------------------
|
|
||||||
// helpers
|
// some helpers for axi
|
||||||
//------------------------------------------------------------
|
task automatic axis_send_byte(input logic [7:0] data, input logic last);
|
||||||
|
begin
|
||||||
|
@(negedge eth_clk_in);
|
||||||
|
s_axis_tdata <= data;
|
||||||
|
s_axis_tvalid <= 1'b1;
|
||||||
|
s_axis_tlast <= last;
|
||||||
|
|
||||||
|
@(posedge eth_clk_in);
|
||||||
|
while (!s_axis_tready) begin
|
||||||
|
@(posedge eth_clk_in);
|
||||||
|
end
|
||||||
|
|
||||||
|
s_axis_tvalid <= 1'b0;
|
||||||
|
s_axis_tlast <= 1'b0;
|
||||||
|
s_axis_tdata <= '0;
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
task automatic send_cmd(input logic [7:0] cmd);
|
task automatic send_cmd(input logic [7:0] cmd);
|
||||||
begin
|
begin
|
||||||
@(negedge ctrl_clk);
|
axis_send_byte(cmd, 1'b1);
|
||||||
|
|
||||||
case (cmd)
|
|
||||||
|
|
||||||
8'h0F: begin
|
|
||||||
rst_soft <= 1'b1;
|
|
||||||
|
|
||||||
@(posedge ctrl_clk);
|
|
||||||
|
|
||||||
rst_soft <= 1'b0;
|
|
||||||
end
|
|
||||||
|
|
||||||
8'hF0: begin
|
|
||||||
start <= 1'b1;
|
|
||||||
|
|
||||||
@(posedge ctrl_clk);
|
|
||||||
|
|
||||||
start <= 1'b0;
|
|
||||||
end
|
|
||||||
|
|
||||||
default:
|
|
||||||
$fatal(1, "Unsupported command %h", cmd);
|
|
||||||
|
|
||||||
endcase
|
|
||||||
end
|
end
|
||||||
endtask
|
endtask
|
||||||
|
|
||||||
@@ -173,65 +140,47 @@ module tb_control;
|
|||||||
input logic [31:0] pulse_period,
|
input logic [31:0] pulse_period,
|
||||||
input logic [15:0] pulse_num,
|
input logic [15:0] pulse_num,
|
||||||
input logic [15:0] pulse_height_raw,
|
input logic [15:0] pulse_height_raw,
|
||||||
input logic [31:0] pulse_period_adc,
|
input logic [31:0] pulse_period_adc
|
||||||
input logic [31:0] window_size
|
);
|
||||||
);
|
logic [127:0] payload;
|
||||||
|
int i;
|
||||||
|
begin
|
||||||
|
// little-endian payload layout:
|
||||||
|
// [31:0] pulse_width
|
||||||
|
// [63:32] pulse_period
|
||||||
|
// [79:64] pulse_num
|
||||||
|
// [95:80] pulse_height_raw
|
||||||
|
// [127:96] pulse_period_ADC
|
||||||
|
|
||||||
logic [159:0] payload;
|
payload = {pulse_period_adc, pulse_height_raw, pulse_num, pulse_period, pulse_width};
|
||||||
|
|
||||||
begin
|
axis_send_byte(8'h88, 1'b0); // CMD_SET_DATA
|
||||||
|
|
||||||
payload = {
|
for (i = 0; i < 16; i++) begin
|
||||||
window_size,
|
axis_send_byte(payload[i*8 +: 8], (i == 15));
|
||||||
pulse_period_adc,
|
end
|
||||||
pulse_height_raw,
|
end
|
||||||
pulse_num,
|
endtask
|
||||||
pulse_period,
|
|
||||||
pulse_width
|
|
||||||
};
|
|
||||||
|
|
||||||
@(negedge ctrl_clk);
|
|
||||||
|
|
||||||
cfg_bus_input <= payload;
|
|
||||||
cfg_bus_valid <= 1'b1;
|
|
||||||
|
|
||||||
@(posedge ctrl_clk);
|
|
||||||
|
|
||||||
cfg_bus_valid <= 1'b0;
|
|
||||||
cfg_bus_input <= '0;
|
|
||||||
|
|
||||||
end
|
|
||||||
endtask
|
|
||||||
|
|
||||||
task automatic pulse_finish;
|
task automatic pulse_finish;
|
||||||
begin
|
begin
|
||||||
@(posedge adc_clk_in);
|
@(posedge adc_clk_in);
|
||||||
finish <= 1'b1;
|
finish <= 1'b1;
|
||||||
|
|
||||||
@(posedge adc_clk_in);
|
@(posedge adc_clk_in);
|
||||||
finish <= 1'b0;
|
finish <= 1'b0;
|
||||||
end
|
end
|
||||||
endtask
|
endtask
|
||||||
|
|
||||||
//------------------------------------------------------------
|
|
||||||
// waiters
|
|
||||||
//------------------------------------------------------------
|
|
||||||
|
|
||||||
|
// waiters
|
||||||
task automatic wait_dac_rst_count(input int expected, input int max_cycles = 100);
|
task automatic wait_dac_rst_count(input int expected, input int max_cycles = 100);
|
||||||
int i;
|
int i;
|
||||||
begin
|
begin
|
||||||
for (i = 0; i < max_cycles; i++) begin
|
for (i = 0; i < max_cycles; i++) begin
|
||||||
@(posedge dac_clk_in);
|
@(posedge dac_clk_in);
|
||||||
|
if (dac_rst_count >= expected) return;
|
||||||
if (dac_rst_count >= expected)
|
|
||||||
return;
|
|
||||||
end
|
end
|
||||||
|
$fatal(1, "Timeout waiting for dac_rst_count >= %0d, current=%0d", expected, dac_rst_count);
|
||||||
$fatal(1,
|
|
||||||
"Timeout waiting for dac_rst_count >= %0d, current=%0d",
|
|
||||||
expected,
|
|
||||||
dac_rst_count
|
|
||||||
);
|
|
||||||
end
|
end
|
||||||
endtask
|
endtask
|
||||||
|
|
||||||
@@ -240,16 +189,9 @@ endtask
|
|||||||
begin
|
begin
|
||||||
for (i = 0; i < max_cycles; i++) begin
|
for (i = 0; i < max_cycles; i++) begin
|
||||||
@(posedge adc_clk_in);
|
@(posedge adc_clk_in);
|
||||||
|
if (adc_rst_count >= expected) return;
|
||||||
if (adc_rst_count >= expected)
|
|
||||||
return;
|
|
||||||
end
|
end
|
||||||
|
$fatal(1, "Timeout waiting for adc_rst_count >= %0d, current=%0d", expected, adc_rst_count);
|
||||||
$fatal(1,
|
|
||||||
"Timeout waiting for adc_rst_count >= %0d, current=%0d",
|
|
||||||
expected,
|
|
||||||
adc_rst_count
|
|
||||||
);
|
|
||||||
end
|
end
|
||||||
endtask
|
endtask
|
||||||
|
|
||||||
@@ -258,16 +200,9 @@ endtask
|
|||||||
begin
|
begin
|
||||||
for (i = 0; i < max_cycles; i++) begin
|
for (i = 0; i < max_cycles; i++) begin
|
||||||
@(posedge dac_clk_in);
|
@(posedge dac_clk_in);
|
||||||
|
if (dac_start_count >= expected) return;
|
||||||
if (dac_start_count >= expected)
|
|
||||||
return;
|
|
||||||
end
|
end
|
||||||
|
$fatal(1, "Timeout waiting for dac_start_count >= %0d, current=%0d", expected, dac_start_count);
|
||||||
$fatal(1,
|
|
||||||
"Timeout waiting for dac_start_count >= %0d, current=%0d",
|
|
||||||
expected,
|
|
||||||
dac_start_count
|
|
||||||
);
|
|
||||||
end
|
end
|
||||||
endtask
|
endtask
|
||||||
|
|
||||||
@@ -276,290 +211,165 @@ endtask
|
|||||||
begin
|
begin
|
||||||
for (i = 0; i < max_cycles; i++) begin
|
for (i = 0; i < max_cycles; i++) begin
|
||||||
@(posedge adc_clk_in);
|
@(posedge adc_clk_in);
|
||||||
|
if (adc_start_count >= expected) return;
|
||||||
if (adc_start_count >= expected)
|
|
||||||
return;
|
|
||||||
end
|
end
|
||||||
|
$fatal(1, "Timeout waiting for adc_start_count >= %0d, current=%0d", expected, adc_start_count);
|
||||||
$fatal(1,
|
|
||||||
"Timeout waiting for adc_start_count >= %0d, current=%0d",
|
|
||||||
expected,
|
|
||||||
adc_start_count
|
|
||||||
);
|
|
||||||
end
|
end
|
||||||
endtask
|
endtask
|
||||||
|
|
||||||
task automatic wait_cfg_applied(
|
task automatic wait_cfg_applied(
|
||||||
|
|
||||||
input logic [31:0] exp_pulse_width,
|
input logic [31:0] exp_pulse_width,
|
||||||
input logic [31:0] exp_pulse_period,
|
input logic [31:0] exp_pulse_period,
|
||||||
input logic [15:0] exp_pulse_num,
|
input logic [15:0] exp_pulse_num,
|
||||||
input logic [15:0] exp_pulse_height_raw,
|
input logic [15:0] exp_pulse_height_raw,
|
||||||
input logic [31:0] exp_pulse_period_adc,
|
input logic [31:0] exp_pulse_period_adc,
|
||||||
input logic [31:0] exp_window_size,
|
|
||||||
input int max_cycles = 200
|
input int max_cycles = 200
|
||||||
);
|
);
|
||||||
|
logic [DAC_DATA_WIDTH-1:0] exp_dac_height;
|
||||||
|
int i;
|
||||||
|
begin
|
||||||
|
exp_dac_height = exp_pulse_height_raw[DAC_DATA_WIDTH-1:0];
|
||||||
|
|
||||||
logic [DAC_DATA_WIDTH-1:0] exp_height;
|
for (i = 0; i < max_cycles; i++) begin
|
||||||
|
@(posedge eth_clk_in);
|
||||||
int i;
|
if ((dac_pulse_width === exp_pulse_width ) &&
|
||||||
|
(dac_pulse_period === exp_pulse_period) &&
|
||||||
begin
|
(dac_pulse_num === exp_pulse_num ) &&
|
||||||
|
(dac_pulse_height === exp_dac_height ) &&
|
||||||
exp_height = exp_pulse_height_raw[DAC_DATA_WIDTH-1:0];
|
(adc_pulse_period === exp_pulse_period_adc) &&
|
||||||
|
(adc_pulse_num === exp_pulse_num )) begin
|
||||||
for(i=0;i<max_cycles;i++) begin
|
|
||||||
|
|
||||||
@(posedge ctrl_clk);
|
|
||||||
|
|
||||||
if(
|
|
||||||
|
|
||||||
dac_pulse_width == exp_pulse_width &&
|
|
||||||
dac_pulse_period == exp_pulse_period &&
|
|
||||||
dac_pulse_num == exp_pulse_num &&
|
|
||||||
dac_pulse_height == exp_height &&
|
|
||||||
|
|
||||||
adc_pulse_period == exp_pulse_period_adc &&
|
|
||||||
adc_pulse_num == exp_pulse_num &&
|
|
||||||
adc_window_size == exp_window_size
|
|
||||||
|
|
||||||
)
|
|
||||||
return;
|
return;
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
$fatal("Configuration timeout");
|
$fatal(1,
|
||||||
|
"Timeout waiting config outputs. Got: dac_width=%h dac_period=%h dac_num=%h dac_height=%h adc_period=%h adc_num=%h",
|
||||||
|
dac_pulse_width, dac_pulse_period, dac_pulse_num, dac_pulse_height,
|
||||||
|
adc_pulse_period, adc_pulse_num
|
||||||
|
);
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
end
|
|
||||||
endtask
|
|
||||||
|
|
||||||
//------------------------------------------------------------
|
|
||||||
// Test sequence
|
// Test sequence
|
||||||
//------------------------------------------------------------
|
|
||||||
|
|
||||||
logic [31:0] test_pulse_width;
|
logic [31:0] test_pulse_width;
|
||||||
logic [31:0] test_pulse_period;
|
logic [31:0] test_pulse_period;
|
||||||
logic [15:0] test_pulse_num;
|
logic [15:0] test_pulse_num;
|
||||||
logic [15:0] test_pulse_height_raw;
|
logic [15:0] test_pulse_height_raw;
|
||||||
logic [31:0] test_pulse_period_adc;
|
logic [31:0] test_pulse_period_adc;
|
||||||
logic [31:0] test_window_size;
|
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
// defaults
|
// defaults
|
||||||
rst_n = 1'b0;
|
rst_n = 1'b0;
|
||||||
rst_soft = 1'b0;
|
s_axis_tdata = '0;
|
||||||
|
s_axis_tvalid = 1'b0;
|
||||||
start = 1'b0;
|
s_axis_tlast = 1'b0;
|
||||||
finish = 1'b0;
|
finish = 1'b0;
|
||||||
|
|
||||||
cfg_bus_input = '0;
|
|
||||||
cfg_bus_valid = 1'b0;
|
|
||||||
|
|
||||||
test_pulse_width = 32'h11223344;
|
test_pulse_width = 32'h11223344;
|
||||||
test_pulse_period = 32'h55667788;
|
test_pulse_period = 32'h55667788;
|
||||||
test_pulse_num = 16'hA1B2;
|
test_pulse_num = 16'hA1B2;
|
||||||
test_pulse_height_raw = 16'h0CDE; // for DAC_DATA_WIDTH=12 => 12'hCDE
|
test_pulse_height_raw = 16'h0CDE; // for DAC_DATA_WIDTH=12 => 12'hCDE
|
||||||
test_pulse_period_adc = 32'h50607080;
|
test_pulse_period_adc = 32'h50607080;
|
||||||
test_window_size = 32'hABCDEF55;
|
|
||||||
|
|
||||||
repeat (10) @(posedge ctrl_clk);
|
repeat (10) @(posedge eth_clk_in);
|
||||||
rst_n = 1'b1;
|
rst_n = 1'b1;
|
||||||
|
|
||||||
repeat (10) @(posedge ctrl_clk);
|
repeat (10) @(posedge eth_clk_in);
|
||||||
|
|
||||||
//--------------------------------------------------------
|
|
||||||
// TEST 1: soft_reset
|
|
||||||
//--------------------------------------------------------
|
|
||||||
|
|
||||||
$display("[%0t] TEST 1: soft_reset", $time);
|
$display("[%0t] TEST 1: soft_reset", $time);
|
||||||
|
|
||||||
send_cmd(8'h0F);
|
send_cmd(8'h0F);
|
||||||
|
|
||||||
wait_dac_rst_count(1);
|
wait_dac_rst_count(1);
|
||||||
wait_adc_rst_count(1);
|
wait_adc_rst_count(1);
|
||||||
|
|
||||||
if (dac_rst_count != 1) begin
|
if (dac_rst_count != 1) begin
|
||||||
$fatal(1,
|
$fatal(1, "Expected exactly one dac_rst pulse after first soft_reset, got %0d", dac_rst_count);
|
||||||
"Expected exactly one dac_rst pulse after first soft_reset, got %0d",
|
|
||||||
dac_rst_count
|
|
||||||
);
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if (adc_rst_count != 1) begin
|
if (adc_rst_count != 1) begin
|
||||||
$fatal(1,
|
$fatal(1, "Expected exactly one adc_rst pulse after first soft_reset, got %0d", adc_rst_count);
|
||||||
"Expected exactly one adc_rst pulse after first soft_reset, got %0d",
|
|
||||||
adc_rst_count
|
|
||||||
);
|
|
||||||
end
|
end
|
||||||
|
|
||||||
$display("[%0t] TEST 1 passed", $time);
|
$display("[%0t] TEST 1 passed", $time);
|
||||||
|
|
||||||
//--------------------------------------------------------
|
|
||||||
// TEST 2: set_data
|
|
||||||
//--------------------------------------------------------
|
|
||||||
|
|
||||||
$display("[%0t] TEST 2: set_data", $time);
|
$display("[%0t] TEST 2: set_data", $time);
|
||||||
|
|
||||||
send_set_data(
|
send_set_data(
|
||||||
|
|
||||||
test_pulse_width,
|
test_pulse_width,
|
||||||
test_pulse_period,
|
test_pulse_period,
|
||||||
test_pulse_num,
|
test_pulse_num,
|
||||||
test_pulse_height_raw,
|
test_pulse_height_raw,
|
||||||
test_pulse_period_adc,
|
test_pulse_period_adc
|
||||||
test_window_size
|
);
|
||||||
|
|
||||||
);
|
|
||||||
|
|
||||||
wait_cfg_applied(
|
wait_cfg_applied(
|
||||||
|
|
||||||
test_pulse_width,
|
test_pulse_width,
|
||||||
test_pulse_period,
|
test_pulse_period,
|
||||||
test_pulse_num,
|
test_pulse_num,
|
||||||
test_pulse_height_raw,
|
test_pulse_height_raw,
|
||||||
test_pulse_period_adc,
|
test_pulse_period_adc
|
||||||
test_window_size
|
);
|
||||||
|
|
||||||
);
|
|
||||||
|
|
||||||
if (dac_pulse_width !== 32'h11223344) begin
|
if (dac_pulse_width !== 32'h11223344) begin
|
||||||
$fatal(1,
|
$fatal(1, "dac_pulse_width mismatch: got %h expected %h", dac_pulse_width, 32'h11223344);
|
||||||
"dac_pulse_width mismatch: got %h expected %h",
|
|
||||||
dac_pulse_width,
|
|
||||||
32'h11223344
|
|
||||||
);
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if (dac_pulse_period !== 32'h55667788) begin
|
if (dac_pulse_period !== 32'h55667788) begin
|
||||||
$fatal(1,
|
$fatal(1, "dac_pulse_period mismatch: got %h expected %h", dac_pulse_period, 32'h55667788);
|
||||||
"dac_pulse_period mismatch: got %h expected %h",
|
|
||||||
dac_pulse_period,
|
|
||||||
32'h55667788
|
|
||||||
);
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if (dac_pulse_num !== 16'hA1B2) begin
|
if (dac_pulse_num !== 16'hA1B2) begin
|
||||||
$fatal(1,
|
$fatal(1, "dac_pulse_num mismatch: got %h expected %h", dac_pulse_num, 16'hA1B2);
|
||||||
"dac_pulse_num mismatch: got %h expected %h",
|
|
||||||
dac_pulse_num,
|
|
||||||
16'hA1B2
|
|
||||||
);
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if (dac_pulse_height !== 12'hCDE) begin
|
if (dac_pulse_height !== 12'hCDE) begin
|
||||||
$fatal(1,
|
$fatal(1, "dac_pulse_height mismatch: got %h expected %h", dac_pulse_height, 12'hCDE);
|
||||||
"dac_pulse_height mismatch: got %h expected %h",
|
|
||||||
dac_pulse_height,
|
|
||||||
12'hCDE
|
|
||||||
);
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if (adc_pulse_period !== 32'h50607080) begin
|
if (adc_pulse_period !== 32'h50607080) begin
|
||||||
$fatal(1,
|
$fatal(1, "adc_pulse_period mismatch: got %h expected %h", adc_pulse_period, 32'h50607080);
|
||||||
"adc_pulse_period mismatch: got %h expected %h",
|
|
||||||
adc_pulse_period,
|
|
||||||
32'h50607080
|
|
||||||
);
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if (adc_pulse_num !== 16'hA1B2) begin
|
if (adc_pulse_num !== 16'hA1B2) begin
|
||||||
$fatal(1,
|
$fatal(1, "adc_pulse_num mismatch: got %h expected %h", adc_pulse_num, 16'hA1B2);
|
||||||
"adc_pulse_num mismatch: got %h expected %h",
|
|
||||||
adc_pulse_num,
|
|
||||||
16'hA1B2
|
|
||||||
);
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if(adc_window_size != test_window_size)
|
|
||||||
|
|
||||||
$fatal(
|
|
||||||
"adc_window_size mismatch. got=%h expected=%h",
|
|
||||||
adc_window_size,
|
|
||||||
test_window_size
|
|
||||||
);
|
|
||||||
|
|
||||||
$display("[%0t] TEST 2 passed", $time);
|
$display("[%0t] TEST 2 passed", $time);
|
||||||
|
|
||||||
repeat (20) @(posedge ctrl_clk);
|
repeat (20) @(posedge eth_clk_in);
|
||||||
|
|
||||||
//--------------------------------------------------------
|
|
||||||
// TEST 3: start
|
|
||||||
//--------------------------------------------------------
|
|
||||||
|
|
||||||
$display("[%0t] TEST 3: start", $time);
|
$display("[%0t] TEST 3: start", $time);
|
||||||
|
|
||||||
send_cmd(8'hF0);
|
send_cmd(8'hF0);
|
||||||
|
|
||||||
wait_dac_start_count(1);
|
wait_dac_start_count(1);
|
||||||
wait_adc_start_count(1);
|
wait_adc_start_count(1);
|
||||||
|
|
||||||
if (dac_start_count != 1) begin
|
if (dac_start_count != 1) begin
|
||||||
$fatal(1,
|
$fatal(1, "Expected exactly one dac_start pulse after first start, got %0d", dac_start_count);
|
||||||
"Expected exactly one dac_start pulse after first start, got %0d",
|
|
||||||
dac_start_count
|
|
||||||
);
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if (adc_start_count != 1) begin
|
if (adc_start_count != 1) begin
|
||||||
$fatal(1,
|
$fatal(1, "Expected exactly one adc_start pulse after first start, got %0d", adc_start_count);
|
||||||
"Expected exactly one adc_start pulse after first start, got %0d",
|
|
||||||
adc_start_count
|
|
||||||
);
|
|
||||||
end
|
|
||||||
|
|
||||||
if (!busy) begin
|
|
||||||
$fatal(1,
|
|
||||||
"busy must be asserted after start"
|
|
||||||
);
|
|
||||||
end
|
end
|
||||||
|
|
||||||
$display("[%0t] TEST 3 start pulses passed", $time);
|
$display("[%0t] TEST 3 start pulses passed", $time);
|
||||||
|
|
||||||
//--------------------------------------------------------
|
|
||||||
// release busy by finish pulse from ADC domain
|
// release busy by finish pulse from ADC domain
|
||||||
//--------------------------------------------------------
|
|
||||||
|
|
||||||
$display("[%0t] Sending finish pulse", $time);
|
$display("[%0t] Sending finish pulse", $time);
|
||||||
|
|
||||||
pulse_finish();
|
pulse_finish();
|
||||||
|
|
||||||
repeat (20) @(posedge ctrl_clk);
|
// a bit of wait for finish CDC back to ETH
|
||||||
|
repeat (20) @(posedge eth_clk_in);
|
||||||
|
|
||||||
if (busy) begin
|
|
||||||
$fatal(1,
|
|
||||||
"busy was not cleared after finish pulse"
|
|
||||||
);
|
|
||||||
end
|
|
||||||
|
|
||||||
//--------------------------------------------------------
|
|
||||||
// sanity check that commands are accepted again after finish
|
// sanity check that commands are accepted again after finish
|
||||||
//--------------------------------------------------------
|
|
||||||
|
|
||||||
$display("[%0t] TEST 4: soft_reset after finish", $time);
|
$display("[%0t] TEST 4: soft_reset after finish", $time);
|
||||||
|
|
||||||
send_cmd(8'h0F);
|
send_cmd(8'h0F);
|
||||||
|
|
||||||
wait_dac_rst_count(2);
|
wait_dac_rst_count(2);
|
||||||
wait_adc_rst_count(2);
|
wait_adc_rst_count(2);
|
||||||
|
|
||||||
if (dac_rst_count != 2) begin
|
if (dac_rst_count != 2) begin
|
||||||
$fatal(1,
|
$fatal(1, "Expected exactly two dac_rst pulses total, got %0d", dac_rst_count);
|
||||||
"Expected exactly two dac_rst pulses total, got %0d",
|
|
||||||
dac_rst_count
|
|
||||||
);
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if (adc_rst_count != 2) begin
|
if (adc_rst_count != 2) begin
|
||||||
$fatal(1,
|
$fatal(1, "Expected exactly two adc_rst pulses total, got %0d", adc_rst_count);
|
||||||
"Expected exactly two adc_rst pulses total, got %0d",
|
|
||||||
adc_rst_count
|
|
||||||
);
|
|
||||||
end
|
end
|
||||||
|
|
||||||
$display("[%0t] TEST 4 passed", $time);
|
$display("[%0t] TEST 4 passed", $time);
|
||||||
|
|
||||||
//--------------------------------------------------------
|
|
||||||
|
|
||||||
$display("==============================================");
|
$display("==============================================");
|
||||||
$display("ALL BASIC TESTS PASSED");
|
$display("ALL BASIC TESTS PASSED");
|
||||||
$display("dac_rst_count = %0d", dac_rst_count);
|
$display("dac_rst_count = %0d", dac_rst_count);
|
||||||
@@ -568,170 +378,8 @@ endtask
|
|||||||
$display("adc_start_count = %0d", adc_start_count);
|
$display("adc_start_count = %0d", adc_start_count);
|
||||||
$display("==============================================");
|
$display("==============================================");
|
||||||
|
|
||||||
#50;
|
#100;
|
||||||
|
|
||||||
//--------------------------------------------------------
|
|
||||||
// TEST 2.1: set_data
|
|
||||||
//--------------------------------------------------------
|
|
||||||
|
|
||||||
test_pulse_width = 32'h12121212;
|
|
||||||
test_pulse_period = 32'h34343434;
|
|
||||||
test_pulse_num = 16'h1A2B;
|
|
||||||
test_pulse_height_raw = 16'hC0ED; // for DAC_DATA_WIDTH=12 => 12'hCDE
|
|
||||||
test_pulse_period_adc = 32'h56565656;
|
|
||||||
test_window_size = 32'h01020304;
|
|
||||||
|
|
||||||
$display("[%0t] TEST 2.1: set_data", $time);
|
|
||||||
|
|
||||||
send_set_data(
|
|
||||||
test_pulse_width,
|
|
||||||
test_pulse_period,
|
|
||||||
test_pulse_num,
|
|
||||||
test_pulse_height_raw,
|
|
||||||
test_pulse_period_adc,
|
|
||||||
test_window_size
|
|
||||||
);
|
|
||||||
|
|
||||||
wait_cfg_applied(
|
|
||||||
test_pulse_width,
|
|
||||||
test_pulse_period,
|
|
||||||
test_pulse_num,
|
|
||||||
test_pulse_height_raw,
|
|
||||||
test_pulse_period_adc,
|
|
||||||
test_window_size
|
|
||||||
);
|
|
||||||
|
|
||||||
if (dac_pulse_width !== 32'h12121212) begin
|
|
||||||
$fatal(1,
|
|
||||||
"dac_pulse_width mismatch: got %h expected %h",
|
|
||||||
dac_pulse_width,
|
|
||||||
32'h12121212
|
|
||||||
);
|
|
||||||
end
|
|
||||||
|
|
||||||
if (dac_pulse_period !== 32'h34343434) begin
|
|
||||||
$fatal(1,
|
|
||||||
"dac_pulse_period mismatch: got %h expected %h",
|
|
||||||
dac_pulse_period,
|
|
||||||
32'h34343434
|
|
||||||
);
|
|
||||||
end
|
|
||||||
|
|
||||||
if (dac_pulse_num !== 16'h1A2B) begin
|
|
||||||
$fatal(1,
|
|
||||||
"dac_pulse_num mismatch: got %h expected %h",
|
|
||||||
dac_pulse_num,
|
|
||||||
16'h1A2B
|
|
||||||
);
|
|
||||||
end
|
|
||||||
|
|
||||||
if (dac_pulse_height !== 12'hC0ED) begin
|
|
||||||
$fatal(1,
|
|
||||||
"dac_pulse_height mismatch: got %h expected %h",
|
|
||||||
dac_pulse_height,
|
|
||||||
12'hC0ED
|
|
||||||
);
|
|
||||||
end
|
|
||||||
|
|
||||||
if (adc_pulse_period !== 32'h56565656) begin
|
|
||||||
$fatal(1,
|
|
||||||
"adc_pulse_period mismatch: got %h expected %h",
|
|
||||||
adc_pulse_period,
|
|
||||||
32'h56565656
|
|
||||||
);
|
|
||||||
end
|
|
||||||
|
|
||||||
$display("[%0t] TEST 2.1 passed", $time);
|
|
||||||
|
|
||||||
repeat (20) @(posedge ctrl_clk);
|
|
||||||
|
|
||||||
//--------------------------------------------------------
|
|
||||||
// TEST 3.1: start
|
|
||||||
//--------------------------------------------------------
|
|
||||||
|
|
||||||
$display("[%0t] TEST 3.1: start", $time);
|
|
||||||
|
|
||||||
send_cmd(8'hF0);
|
|
||||||
|
|
||||||
wait_dac_start_count(2);
|
|
||||||
wait_adc_start_count(2);
|
|
||||||
|
|
||||||
if (dac_start_count != 2) begin
|
|
||||||
$fatal(1,
|
|
||||||
"Expected exactly one dac_start pulse after first start, got %0d",
|
|
||||||
dac_start_count
|
|
||||||
);
|
|
||||||
end
|
|
||||||
|
|
||||||
if (adc_start_count != 2) begin
|
|
||||||
$fatal(1,
|
|
||||||
"Expected exactly one adc_start pulse after first start, got %0d",
|
|
||||||
adc_start_count
|
|
||||||
);
|
|
||||||
end
|
|
||||||
|
|
||||||
if (!busy) begin
|
|
||||||
$fatal(1,
|
|
||||||
"busy must be asserted after start"
|
|
||||||
);
|
|
||||||
end
|
|
||||||
|
|
||||||
$display("[%0t] TEST 3.1 start pulses passed", $time);
|
|
||||||
|
|
||||||
//--------------------------------------------------------
|
|
||||||
// release busy by finish pulse from ADC domain
|
|
||||||
//--------------------------------------------------------
|
|
||||||
|
|
||||||
$display("[%0t] Sending finish pulse", $time);
|
|
||||||
|
|
||||||
pulse_finish();
|
|
||||||
|
|
||||||
repeat (20) @(posedge ctrl_clk);
|
|
||||||
|
|
||||||
if (busy) begin
|
|
||||||
$fatal(1,
|
|
||||||
"busy was not cleared after finish pulse"
|
|
||||||
);
|
|
||||||
end
|
|
||||||
|
|
||||||
//--------------------------------------------------------
|
|
||||||
// sanity check that commands are accepted again after finish
|
|
||||||
//--------------------------------------------------------
|
|
||||||
|
|
||||||
$display("[%0t] TEST 4.1: soft_reset after finish", $time);
|
|
||||||
|
|
||||||
send_cmd(8'h0F);
|
|
||||||
|
|
||||||
wait_dac_rst_count(2);
|
|
||||||
wait_adc_rst_count(2);
|
|
||||||
|
|
||||||
if (dac_rst_count != 2) begin
|
|
||||||
$fatal(1,
|
|
||||||
"Expected exactly two dac_rst pulses total, got %0d",
|
|
||||||
dac_rst_count
|
|
||||||
);
|
|
||||||
end
|
|
||||||
|
|
||||||
if (adc_rst_count != 2) begin
|
|
||||||
$fatal(1,
|
|
||||||
"Expected exactly two adc_rst pulses total, got %0d",
|
|
||||||
adc_rst_count
|
|
||||||
);
|
|
||||||
end
|
|
||||||
|
|
||||||
$display("[%0t] TEST 4.1 passed", $time);
|
|
||||||
|
|
||||||
//--------------------------------------------------------
|
|
||||||
|
|
||||||
$display("==============================================");
|
|
||||||
$display("ALL BASIC TESTS PASSED");
|
|
||||||
$display("dac_rst_count = %0d", dac_rst_count);
|
|
||||||
$display("adc_rst_count = %0d", adc_rst_count);
|
|
||||||
$display("dac_start_count = %0d", dac_start_count);
|
|
||||||
$display("adc_start_count = %0d", adc_start_count);
|
|
||||||
$display("==============================================");
|
|
||||||
$finish;
|
$finish;
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
@@ -11,226 +11,187 @@
|
|||||||
</db_ref>
|
</db_ref>
|
||||||
</db_ref_list>
|
</db_ref_list>
|
||||||
<zoom_setting>
|
<zoom_setting>
|
||||||
<ZoomStartTime time="160.614 ns"></ZoomStartTime>
|
<ZoomStartTime time="0.676 ns"></ZoomStartTime>
|
||||||
<ZoomEndTime time="1,564.737 ns"></ZoomEndTime>
|
<ZoomEndTime time="645.677 ns"></ZoomEndTime>
|
||||||
<Cursor1Time time="1,330.716 ns"></Cursor1Time>
|
<Cursor1Time time="349.676 ns"></Cursor1Time>
|
||||||
</zoom_setting>
|
</zoom_setting>
|
||||||
<column_width_setting>
|
<column_width_setting>
|
||||||
<NameColumnWidth column_width="479"></NameColumnWidth>
|
<NameColumnWidth column_width="558"></NameColumnWidth>
|
||||||
<ValueColumnWidth column_width="116"></ValueColumnWidth>
|
<ValueColumnWidth column_width="61"></ValueColumnWidth>
|
||||||
</column_width_setting>
|
</column_width_setting>
|
||||||
<WVObjectSize size="34" />
|
<WVObjectSize size="23" />
|
||||||
<wvobject fp_name="/tb_control/dac_clk_in" type="logic">
|
<wvobject type="logic" fp_name="/tb_control/eth_clk_in">
|
||||||
|
<obj_property name="ElementShortName">eth_clk_in</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">eth_clk_in</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#008080</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject type="logic" fp_name="/tb_control/dac_clk_in">
|
||||||
<obj_property name="ElementShortName">dac_clk_in</obj_property>
|
<obj_property name="ElementShortName">dac_clk_in</obj_property>
|
||||||
<obj_property name="ObjectShortName">dac_clk_in</obj_property>
|
<obj_property name="ObjectShortName">dac_clk_in</obj_property>
|
||||||
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
</wvobject>
|
</wvobject>
|
||||||
<wvobject fp_name="/tb_control/adc_clk_in" type="logic">
|
<wvobject type="logic" fp_name="/tb_control/adc_clk_in">
|
||||||
<obj_property name="ElementShortName">adc_clk_in</obj_property>
|
<obj_property name="ElementShortName">adc_clk_in</obj_property>
|
||||||
<obj_property name="ObjectShortName">adc_clk_in</obj_property>
|
<obj_property name="ObjectShortName">adc_clk_in</obj_property>
|
||||||
</wvobject>
|
</wvobject>
|
||||||
<wvobject fp_name="/tb_control/rst_n" type="logic">
|
<wvobject type="logic" fp_name="/tb_control/rst_n">
|
||||||
<obj_property name="ElementShortName">rst_n</obj_property>
|
<obj_property name="ElementShortName">rst_n</obj_property>
|
||||||
<obj_property name="ObjectShortName">rst_n</obj_property>
|
<obj_property name="ObjectShortName">rst_n</obj_property>
|
||||||
<obj_property name="CustomSignalColor">#800080</obj_property>
|
<obj_property name="CustomSignalColor">#800080</obj_property>
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
</wvobject>
|
</wvobject>
|
||||||
<wvobject fp_name="/tb_control/rst_soft" type="logic">
|
<wvobject type="array" fp_name="/tb_control/s_axis_tdata">
|
||||||
<obj_property name="ElementShortName">rst_soft</obj_property>
|
<obj_property name="ElementShortName">s_axis_tdata[7:0]</obj_property>
|
||||||
<obj_property name="ObjectShortName">rst_soft</obj_property>
|
<obj_property name="ObjectShortName">s_axis_tdata[7:0]</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#008080</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
<obj_property name="Radix">BINARYRADIX</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject type="logic" fp_name="/tb_control/s_axis_tvalid">
|
||||||
|
<obj_property name="ElementShortName">s_axis_tvalid</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">s_axis_tvalid</obj_property>
|
||||||
<obj_property name="CustomSignalColor">#008080</obj_property>
|
<obj_property name="CustomSignalColor">#008080</obj_property>
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
</wvobject>
|
</wvobject>
|
||||||
<wvobject fp_name="/tb_control/start" type="logic">
|
<wvobject type="logic" fp_name="/tb_control/s_axis_tready">
|
||||||
<obj_property name="ElementShortName">start</obj_property>
|
<obj_property name="ElementShortName">s_axis_tready</obj_property>
|
||||||
<obj_property name="ObjectShortName">start</obj_property>
|
<obj_property name="ObjectShortName">s_axis_tready</obj_property>
|
||||||
<obj_property name="CustomSignalColor">#E0FFFF</obj_property>
|
<obj_property name="CustomSignalColor">#008080</obj_property>
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
</wvobject>
|
</wvobject>
|
||||||
<wvobject fp_name="/tb_control/dut/adc_start_pulse" type="logic">
|
<wvobject type="logic" fp_name="/tb_control/s_axis_tlast">
|
||||||
<obj_property name="ElementShortName">adc_start_pulse</obj_property>
|
<obj_property name="ElementShortName">s_axis_tlast</obj_property>
|
||||||
<obj_property name="ObjectShortName">adc_start_pulse</obj_property>
|
<obj_property name="ObjectShortName">s_axis_tlast</obj_property>
|
||||||
</wvobject>
|
<obj_property name="CustomSignalColor">#008080</obj_property>
|
||||||
<wvobject fp_name="/tb_control/dut/dac_start_pulse" type="logic">
|
|
||||||
<obj_property name="ElementShortName">dac_start_pulse</obj_property>
|
|
||||||
<obj_property name="ObjectShortName">dac_start_pulse</obj_property>
|
|
||||||
</wvobject>
|
|
||||||
<wvobject fp_name="/tb_control/busy" type="logic">
|
|
||||||
<obj_property name="ElementShortName">busy</obj_property>
|
|
||||||
<obj_property name="ObjectShortName">busy</obj_property>
|
|
||||||
<obj_property name="CustomSignalColor">#E0FFFF</obj_property>
|
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
</wvobject>
|
</wvobject>
|
||||||
<wvobject fp_name="/tb_control/finish" type="logic">
|
<wvobject type="logic" fp_name="/tb_control/finish">
|
||||||
<obj_property name="ElementShortName">finish</obj_property>
|
<obj_property name="ElementShortName">finish</obj_property>
|
||||||
<obj_property name="ObjectShortName">finish</obj_property>
|
<obj_property name="ObjectShortName">finish</obj_property>
|
||||||
<obj_property name="CustomSignalColor">#FAAFBE</obj_property>
|
<obj_property name="CustomSignalColor">#FAAFBE</obj_property>
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
</wvobject>
|
</wvobject>
|
||||||
<wvobject fp_name="/tb_control/dut/finish_pulse" type="logic">
|
<wvobject type="array" fp_name="/tb_control/dac_pulse_width">
|
||||||
<obj_property name="ElementShortName">finish_pulse</obj_property>
|
|
||||||
<obj_property name="ObjectShortName">finish_pulse</obj_property>
|
|
||||||
</wvobject>
|
|
||||||
<wvobject fp_name="/tb_control/cfg_bus_valid" type="logic">
|
|
||||||
<obj_property name="ElementShortName">cfg_bus_valid</obj_property>
|
|
||||||
<obj_property name="ObjectShortName">cfg_bus_valid</obj_property>
|
|
||||||
<obj_property name="CustomSignalColor">#FF0080</obj_property>
|
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
|
||||||
</wvobject>
|
|
||||||
<wvobject fp_name="/tb_control/cfg_bus_input" type="array">
|
|
||||||
<obj_property name="ElementShortName">cfg_bus_input[159:0]</obj_property>
|
|
||||||
<obj_property name="ObjectShortName">cfg_bus_input[159:0]</obj_property>
|
|
||||||
<obj_property name="CustomSignalColor">#FF0080</obj_property>
|
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
|
||||||
</wvobject>
|
|
||||||
<wvobject fp_name="/tb_control/dac_pulse_width" type="array">
|
|
||||||
<obj_property name="ElementShortName">dac_pulse_width[31:0]</obj_property>
|
<obj_property name="ElementShortName">dac_pulse_width[31:0]</obj_property>
|
||||||
<obj_property name="ObjectShortName">dac_pulse_width[31:0]</obj_property>
|
<obj_property name="ObjectShortName">dac_pulse_width[31:0]</obj_property>
|
||||||
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
</wvobject>
|
</wvobject>
|
||||||
<wvobject fp_name="/tb_control/dac_pulse_period" type="array">
|
<wvobject type="array" fp_name="/tb_control/dac_pulse_period">
|
||||||
<obj_property name="ElementShortName">dac_pulse_period[31:0]</obj_property>
|
<obj_property name="ElementShortName">dac_pulse_period[31:0]</obj_property>
|
||||||
<obj_property name="ObjectShortName">dac_pulse_period[31:0]</obj_property>
|
<obj_property name="ObjectShortName">dac_pulse_period[31:0]</obj_property>
|
||||||
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
</wvobject>
|
</wvobject>
|
||||||
<wvobject fp_name="/tb_control/dac_pulse_height" type="array">
|
<wvobject type="array" fp_name="/tb_control/dac_pulse_height">
|
||||||
<obj_property name="ElementShortName">dac_pulse_height[11:0]</obj_property>
|
<obj_property name="ElementShortName">dac_pulse_height[11:0]</obj_property>
|
||||||
<obj_property name="ObjectShortName">dac_pulse_height[11:0]</obj_property>
|
<obj_property name="ObjectShortName">dac_pulse_height[11:0]</obj_property>
|
||||||
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
<obj_property name="Radix">HEXRADIX</obj_property>
|
<obj_property name="Radix">HEXRADIX</obj_property>
|
||||||
</wvobject>
|
</wvobject>
|
||||||
<wvobject fp_name="/tb_control/dac_pulse_num" type="array">
|
<wvobject type="array" fp_name="/tb_control/dac_pulse_num">
|
||||||
<obj_property name="ElementShortName">dac_pulse_num[15:0]</obj_property>
|
<obj_property name="ElementShortName">dac_pulse_num[15:0]</obj_property>
|
||||||
<obj_property name="ObjectShortName">dac_pulse_num[15:0]</obj_property>
|
<obj_property name="ObjectShortName">dac_pulse_num[15:0]</obj_property>
|
||||||
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
</wvobject>
|
</wvobject>
|
||||||
<wvobject fp_name="/tb_control/adc_pulse_period" type="array">
|
<wvobject type="array" fp_name="/tb_control/adc_pulse_period">
|
||||||
<obj_property name="ElementShortName">adc_pulse_period[31:0]</obj_property>
|
<obj_property name="ElementShortName">adc_pulse_period[31:0]</obj_property>
|
||||||
<obj_property name="ObjectShortName">adc_pulse_period[31:0]</obj_property>
|
<obj_property name="ObjectShortName">adc_pulse_period[31:0]</obj_property>
|
||||||
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
</wvobject>
|
</wvobject>
|
||||||
<wvobject fp_name="/tb_control/adc_pulse_num" type="array">
|
<wvobject type="array" fp_name="/tb_control/adc_pulse_num">
|
||||||
<obj_property name="ElementShortName">adc_pulse_num[15:0]</obj_property>
|
<obj_property name="ElementShortName">adc_pulse_num[15:0]</obj_property>
|
||||||
<obj_property name="ObjectShortName">adc_pulse_num[15:0]</obj_property>
|
<obj_property name="ObjectShortName">adc_pulse_num[15:0]</obj_property>
|
||||||
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
</wvobject>
|
</wvobject>
|
||||||
<wvobject fp_name="/tb_control/adc_window_size" type="array">
|
<wvobject type="logic" fp_name="/tb_control/dac_start">
|
||||||
<obj_property name="ElementShortName">adc_window_size[31:0]</obj_property>
|
|
||||||
<obj_property name="ObjectShortName">adc_window_size[31:0]</obj_property>
|
|
||||||
</wvobject>
|
|
||||||
<wvobject fp_name="/tb_control/dac_start" type="logic">
|
|
||||||
<obj_property name="ElementShortName">dac_start</obj_property>
|
<obj_property name="ElementShortName">dac_start</obj_property>
|
||||||
<obj_property name="ObjectShortName">dac_start</obj_property>
|
<obj_property name="ObjectShortName">dac_start</obj_property>
|
||||||
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
</wvobject>
|
</wvobject>
|
||||||
<wvobject fp_name="/tb_control/adc_start" type="logic">
|
<wvobject type="logic" fp_name="/tb_control/adc_start">
|
||||||
<obj_property name="ElementShortName">adc_start</obj_property>
|
<obj_property name="ElementShortName">adc_start</obj_property>
|
||||||
<obj_property name="ObjectShortName">adc_start</obj_property>
|
<obj_property name="ObjectShortName">adc_start</obj_property>
|
||||||
</wvobject>
|
</wvobject>
|
||||||
<wvobject fp_name="/tb_control/dac_rst" type="logic">
|
<wvobject type="logic" fp_name="/tb_control/dac_rst">
|
||||||
<obj_property name="ElementShortName">dac_rst</obj_property>
|
<obj_property name="ElementShortName">dac_rst</obj_property>
|
||||||
<obj_property name="ObjectShortName">dac_rst</obj_property>
|
<obj_property name="ObjectShortName">dac_rst</obj_property>
|
||||||
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
</wvobject>
|
</wvobject>
|
||||||
<wvobject fp_name="/tb_control/adc_rst" type="logic">
|
<wvobject type="logic" fp_name="/tb_control/adc_rst">
|
||||||
<obj_property name="ElementShortName">adc_rst</obj_property>
|
<obj_property name="ElementShortName">adc_rst</obj_property>
|
||||||
<obj_property name="ObjectShortName">adc_rst</obj_property>
|
<obj_property name="ObjectShortName">adc_rst</obj_property>
|
||||||
</wvobject>
|
</wvobject>
|
||||||
<wvobject fp_name="group499" type="group">
|
<wvobject type="group" fp_name="group499">
|
||||||
<obj_property name="label">tb signals</obj_property>
|
<obj_property name="label">tb signals</obj_property>
|
||||||
<obj_property name="DisplayName">label</obj_property>
|
<obj_property name="DisplayName">label</obj_property>
|
||||||
<wvobject fp_name="/tb_control/dac_rst_count" type="array">
|
<wvobject type="array" fp_name="/tb_control/dac_rst_count">
|
||||||
<obj_property name="ElementShortName">dac_rst_count[31:0]</obj_property>
|
<obj_property name="ElementShortName">dac_rst_count[31:0]</obj_property>
|
||||||
<obj_property name="ObjectShortName">dac_rst_count[31:0]</obj_property>
|
<obj_property name="ObjectShortName">dac_rst_count[31:0]</obj_property>
|
||||||
<obj_property name="CustomSignalColor">#F0E68C</obj_property>
|
<obj_property name="CustomSignalColor">#F0E68C</obj_property>
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
</wvobject>
|
</wvobject>
|
||||||
<wvobject fp_name="/tb_control/adc_rst_count" type="array">
|
<wvobject type="array" fp_name="/tb_control/adc_rst_count">
|
||||||
<obj_property name="ElementShortName">adc_rst_count[31:0]</obj_property>
|
<obj_property name="ElementShortName">adc_rst_count[31:0]</obj_property>
|
||||||
<obj_property name="ObjectShortName">adc_rst_count[31:0]</obj_property>
|
<obj_property name="ObjectShortName">adc_rst_count[31:0]</obj_property>
|
||||||
<obj_property name="CustomSignalColor">#F0E68C</obj_property>
|
<obj_property name="CustomSignalColor">#F0E68C</obj_property>
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
</wvobject>
|
</wvobject>
|
||||||
<wvobject fp_name="/tb_control/dac_start_count" type="array">
|
<wvobject type="array" fp_name="/tb_control/dac_start_count">
|
||||||
<obj_property name="ElementShortName">dac_start_count[31:0]</obj_property>
|
<obj_property name="ElementShortName">dac_start_count[31:0]</obj_property>
|
||||||
<obj_property name="ObjectShortName">dac_start_count[31:0]</obj_property>
|
<obj_property name="ObjectShortName">dac_start_count[31:0]</obj_property>
|
||||||
<obj_property name="CustomSignalColor">#F0E68C</obj_property>
|
<obj_property name="CustomSignalColor">#F0E68C</obj_property>
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
</wvobject>
|
</wvobject>
|
||||||
<wvobject fp_name="/tb_control/adc_start_count" type="array">
|
<wvobject type="array" fp_name="/tb_control/adc_start_count">
|
||||||
<obj_property name="ElementShortName">adc_start_count[31:0]</obj_property>
|
<obj_property name="ElementShortName">adc_start_count[31:0]</obj_property>
|
||||||
<obj_property name="ObjectShortName">adc_start_count[31:0]</obj_property>
|
<obj_property name="ObjectShortName">adc_start_count[31:0]</obj_property>
|
||||||
<obj_property name="CustomSignalColor">#F0E68C</obj_property>
|
<obj_property name="CustomSignalColor">#F0E68C</obj_property>
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
</wvobject>
|
</wvobject>
|
||||||
</wvobject>
|
<wvobject type="array" fp_name="/tb_control/test_pulse_width">
|
||||||
<wvobject fp_name="/tb_control/dut/cfg_req_toggle_adc" type="logic">
|
<obj_property name="ElementShortName">test_pulse_width[31:0]</obj_property>
|
||||||
<obj_property name="ElementShortName">cfg_req_toggle_adc</obj_property>
|
<obj_property name="ObjectShortName">test_pulse_width[31:0]</obj_property>
|
||||||
<obj_property name="ObjectShortName">cfg_req_toggle_adc</obj_property>
|
<obj_property name="CustomSignalColor">#F0E68C</obj_property>
|
||||||
<obj_property name="CustomSignalColor">#FFFF00</obj_property>
|
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
</wvobject>
|
</wvobject>
|
||||||
<wvobject fp_name="/tb_control/dut/cfg_req_toggle_dac" type="logic">
|
<wvobject type="array" fp_name="/tb_control/test_pulse_period">
|
||||||
<obj_property name="ElementShortName">cfg_req_toggle_dac</obj_property>
|
<obj_property name="ElementShortName">test_pulse_period[31:0]</obj_property>
|
||||||
<obj_property name="ObjectShortName">cfg_req_toggle_dac</obj_property>
|
<obj_property name="ObjectShortName">test_pulse_period[31:0]</obj_property>
|
||||||
<obj_property name="CustomSignalColor">#FFFF00</obj_property>
|
<obj_property name="CustomSignalColor">#F0E68C</obj_property>
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
</wvobject>
|
</wvobject>
|
||||||
<wvobject fp_name="/tb_control/dut/cfg_ack_toggle_adc" type="logic">
|
<wvobject type="array" fp_name="/tb_control/test_pulse_num">
|
||||||
|
<obj_property name="ElementShortName">test_pulse_num[15:0]</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">test_pulse_num[15:0]</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#F0E68C</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject type="array" fp_name="/tb_control/test_pulse_height_raw">
|
||||||
|
<obj_property name="ElementShortName">test_pulse_height_raw[15:0]</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">test_pulse_height_raw[15:0]</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#F0E68C</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject type="array" fp_name="/tb_control/DAC_DATA_WIDTH">
|
||||||
|
<obj_property name="ElementShortName">DAC_DATA_WIDTH[31:0]</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">DAC_DATA_WIDTH[31:0]</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject type="logic" fp_name="/tb_control/dut/cfg_ack_toggle_adc">
|
||||||
<obj_property name="ElementShortName">cfg_ack_toggle_adc</obj_property>
|
<obj_property name="ElementShortName">cfg_ack_toggle_adc</obj_property>
|
||||||
<obj_property name="ObjectShortName">cfg_ack_toggle_adc</obj_property>
|
<obj_property name="ObjectShortName">cfg_ack_toggle_adc</obj_property>
|
||||||
<obj_property name="CustomSignalColor">#FF00FF</obj_property>
|
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
|
||||||
</wvobject>
|
</wvobject>
|
||||||
<wvobject fp_name="/tb_control/dut/cfg_ack_toggle_dac" type="logic">
|
<wvobject type="logic" fp_name="/tb_control/dut/cfg_ack_toggle_dac">
|
||||||
<obj_property name="ElementShortName">cfg_ack_toggle_dac</obj_property>
|
<obj_property name="ElementShortName">cfg_ack_toggle_dac</obj_property>
|
||||||
<obj_property name="ObjectShortName">cfg_ack_toggle_dac</obj_property>
|
<obj_property name="ObjectShortName">cfg_ack_toggle_dac</obj_property>
|
||||||
<obj_property name="CustomSignalColor">#FF00FF</obj_property>
|
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
|
||||||
</wvobject>
|
|
||||||
<wvobject fp_name="/tb_control/dut/cfg_wait_adc_ack" type="logic">
|
|
||||||
<obj_property name="ElementShortName">cfg_wait_adc_ack</obj_property>
|
|
||||||
<obj_property name="ObjectShortName">cfg_wait_adc_ack</obj_property>
|
|
||||||
<obj_property name="CustomSignalColor">#0000FF</obj_property>
|
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
|
||||||
</wvobject>
|
|
||||||
<wvobject fp_name="/tb_control/dut/cfg_wait_dac_ack" type="logic">
|
|
||||||
<obj_property name="ElementShortName">cfg_wait_dac_ack</obj_property>
|
|
||||||
<obj_property name="ObjectShortName">cfg_wait_dac_ack</obj_property>
|
|
||||||
<obj_property name="CustomSignalColor">#0000FF</obj_property>
|
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
|
||||||
</wvobject>
|
|
||||||
<wvobject fp_name="/tb_control/dut/cfg_req_pulse_adc" type="logic">
|
|
||||||
<obj_property name="ElementShortName">cfg_req_pulse_adc</obj_property>
|
|
||||||
<obj_property name="ObjectShortName">cfg_req_pulse_adc</obj_property>
|
|
||||||
<obj_property name="CustomSignalColor">#808000</obj_property>
|
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
|
||||||
</wvobject>
|
|
||||||
<wvobject fp_name="/tb_control/dut/cfg_req_pulse_dac" type="logic">
|
|
||||||
<obj_property name="ElementShortName">cfg_req_pulse_dac</obj_property>
|
|
||||||
<obj_property name="ObjectShortName">cfg_req_pulse_dac</obj_property>
|
|
||||||
<obj_property name="CustomSignalColor">#808000</obj_property>
|
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
|
||||||
</wvobject>
|
|
||||||
<wvobject fp_name="/tb_control/dut/cfg_ack_pulse_adc" type="logic">
|
|
||||||
<obj_property name="ElementShortName">cfg_ack_pulse_adc</obj_property>
|
|
||||||
<obj_property name="ObjectShortName">cfg_ack_pulse_adc</obj_property>
|
|
||||||
<obj_property name="CustomSignalColor">#DCDCDC</obj_property>
|
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
|
||||||
</wvobject>
|
|
||||||
<wvobject fp_name="/tb_control/dut/cfg_ack_pulse_dac" type="logic">
|
|
||||||
<obj_property name="ElementShortName">cfg_ack_pulse_dac</obj_property>
|
|
||||||
<obj_property name="ObjectShortName">cfg_ack_pulse_dac</obj_property>
|
|
||||||
<obj_property name="CustomSignalColor">#DCDCDC</obj_property>
|
|
||||||
<obj_property name="UseCustomSignalColor">true</obj_property>
|
|
||||||
</wvobject>
|
</wvobject>
|
||||||
</wave_config>
|
</wave_config>
|
||||||
|
|||||||
@@ -1,338 +0,0 @@
|
|||||||
module tb_controller_wrapper_axil #(
|
|
||||||
parameter int unsigned ADDR_W = 16,
|
|
||||||
parameter int unsigned DATA_W = 32,
|
|
||||||
parameter int unsigned USER_W = 1,
|
|
||||||
|
|
||||||
parameter int unsigned DAC_DATA_WIDTH = 12,
|
|
||||||
|
|
||||||
parameter int unsigned AXI_ADDR_WIDTH = 16,
|
|
||||||
parameter int unsigned AXIS_ID_WIDTH = 8,
|
|
||||||
parameter int unsigned LEN_WIDTH = 20,
|
|
||||||
parameter int unsigned AXIS_USER_WIDTH = 1,
|
|
||||||
parameter int unsigned AXIS_DEST_WIDTH = 8,
|
|
||||||
parameter int unsigned TAG_WIDTH = 8,
|
|
||||||
|
|
||||||
parameter int unsigned READ_DESC_WIDTH = AXI_ADDR_WIDTH + LEN_WIDTH + TAG_WIDTH + AXIS_ID_WIDTH + AXIS_DEST_WIDTH + AXIS_USER_WIDTH,
|
|
||||||
parameter int unsigned WRITE_DESC_WIDTH = AXI_ADDR_WIDTH + LEN_WIDTH + TAG_WIDTH,
|
|
||||||
|
|
||||||
parameter int unsigned READ_STATUS_WIDTH = TAG_WIDTH + 4,
|
|
||||||
parameter int unsigned WRITE_STATUS_WIDTH = LEN_WIDTH + TAG_WIDTH + AXIS_ID_WIDTH + AXIS_DEST_WIDTH + AXIS_USER_WIDTH + 4,
|
|
||||||
|
|
||||||
// ceil(width / 8), чтобы keep/strb не стали слишком узкими для нестандартных ширин типа 12/49/61.
|
|
||||||
parameter int unsigned READ_DESC_KEEP_W = (READ_DESC_WIDTH + 7) / 8,
|
|
||||||
parameter int unsigned WRITE_DESC_KEEP_W = (WRITE_DESC_WIDTH + 7) / 8,
|
|
||||||
parameter int unsigned READ_STATUS_KEEP_W = (READ_STATUS_WIDTH + 7) / 8,
|
|
||||||
parameter int unsigned WRITE_STATUS_KEEP_W = (WRITE_STATUS_WIDTH + 7) / 8
|
|
||||||
)(
|
|
||||||
input logic ctrl_clk,
|
|
||||||
input logic rst,
|
|
||||||
|
|
||||||
input logic [ADDR_W-1:0] s_axil_awaddr,
|
|
||||||
input logic [2:0] s_axil_awprot,
|
|
||||||
input logic s_axil_awvalid,
|
|
||||||
output logic s_axil_awready,
|
|
||||||
|
|
||||||
input logic [DATA_W-1:0] s_axil_wdata,
|
|
||||||
input logic [DATA_W/8-1:0] s_axil_wstrb,
|
|
||||||
input logic s_axil_wvalid,
|
|
||||||
output logic s_axil_wready,
|
|
||||||
|
|
||||||
output logic [1:0] s_axil_bresp,
|
|
||||||
output logic s_axil_bvalid,
|
|
||||||
input logic s_axil_bready,
|
|
||||||
|
|
||||||
input logic [ADDR_W-1:0] s_axil_araddr,
|
|
||||||
input logic [2:0] s_axil_arprot,
|
|
||||||
input logic s_axil_arvalid,
|
|
||||||
output logic s_axil_arready,
|
|
||||||
|
|
||||||
output logic [DATA_W-1:0] s_axil_rdata,
|
|
||||||
output logic [1:0] s_axil_rresp,
|
|
||||||
output logic s_axil_rvalid,
|
|
||||||
input logic s_axil_rready,
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// Минимальный flat-view для DMA AXIS портов.
|
|
||||||
// Наружу оставлены только tdata/tvalid/tready в старом стиле.
|
|
||||||
// Все остальные AXIS поля внутри обёртки завязаны на безопасные значения.
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// DUT master -> testbench: descriptor commands.
|
|
||||||
output logic [READ_DESC_WIDTH-1:0] desc_read_cmd_out,
|
|
||||||
output logic valid_desc_read,
|
|
||||||
input logic ready_desc_read,
|
|
||||||
|
|
||||||
output logic [WRITE_DESC_WIDTH-1:0] desc_write_cmd_out,
|
|
||||||
output logic valid_desc_write,
|
|
||||||
input logic ready_desc_write,
|
|
||||||
|
|
||||||
// testbench -> DUT slave: status commands.
|
|
||||||
input logic [READ_STATUS_WIDTH-1:0] status_read_cmd_in,
|
|
||||||
input logic valid_status_read,
|
|
||||||
output logic ready_status_read,
|
|
||||||
|
|
||||||
input logic [WRITE_STATUS_WIDTH-1:0] status_write_cmd_in,
|
|
||||||
input logic valid_status_write,
|
|
||||||
output logic ready_status_write
|
|
||||||
);
|
|
||||||
|
|
||||||
logic rst_n;
|
|
||||||
assign rst_n = ~rst;
|
|
||||||
|
|
||||||
// Для минимального теста держим все clock domain-ы на одном clock.
|
|
||||||
logic dac_clk_in;
|
|
||||||
logic adc_clk_in;
|
|
||||||
assign dac_clk_in = ctrl_clk;
|
|
||||||
assign adc_clk_in = ctrl_clk;
|
|
||||||
|
|
||||||
logic finish;
|
|
||||||
assign finish = 1'b0;
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// AXI-Lite flat -> axi4l_if
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
axi4l_if #(
|
|
||||||
.ADDR_W(ADDR_W),
|
|
||||||
.DATA_W(DATA_W),
|
|
||||||
.USER_W(USER_W)
|
|
||||||
) axil_bus (
|
|
||||||
.aclk(ctrl_clk),
|
|
||||||
.aresetn(rst_n)
|
|
||||||
);
|
|
||||||
|
|
||||||
axi4l_flat_to_if #(
|
|
||||||
.ADDR_W(ADDR_W),
|
|
||||||
.DATA_W(DATA_W),
|
|
||||||
.USER_W(USER_W)
|
|
||||||
) u_axil_flat_to_if (
|
|
||||||
.s_axil_awaddr (s_axil_awaddr),
|
|
||||||
.s_axil_awprot (s_axil_awprot),
|
|
||||||
.s_axil_awvalid(s_axil_awvalid),
|
|
||||||
.s_axil_awready(s_axil_awready),
|
|
||||||
|
|
||||||
.s_axil_wdata (s_axil_wdata),
|
|
||||||
.s_axil_wstrb (s_axil_wstrb),
|
|
||||||
.s_axil_wvalid (s_axil_wvalid),
|
|
||||||
.s_axil_wready (s_axil_wready),
|
|
||||||
|
|
||||||
.s_axil_bresp (s_axil_bresp),
|
|
||||||
.s_axil_bvalid (s_axil_bvalid),
|
|
||||||
.s_axil_bready (s_axil_bready),
|
|
||||||
|
|
||||||
.s_axil_araddr (s_axil_araddr),
|
|
||||||
.s_axil_arprot (s_axil_arprot),
|
|
||||||
.s_axil_arvalid(s_axil_arvalid),
|
|
||||||
.s_axil_arready(s_axil_arready),
|
|
||||||
|
|
||||||
.s_axil_rdata (s_axil_rdata),
|
|
||||||
.s_axil_rresp (s_axil_rresp),
|
|
||||||
.s_axil_rvalid (s_axil_rvalid),
|
|
||||||
.s_axil_rready (s_axil_rready),
|
|
||||||
|
|
||||||
.m_axil(axil_bus)
|
|
||||||
);
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// AXIS interfaces for the updated controller_wrapper_axil
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
axis_if #(
|
|
||||||
.DATA_W(READ_STATUS_WIDTH),
|
|
||||||
.KEEP_W(READ_STATUS_KEEP_W),
|
|
||||||
.ID_W(AXIS_ID_WIDTH),
|
|
||||||
.DEST_W(AXIS_DEST_WIDTH),
|
|
||||||
.USER_W(AXIS_USER_WIDTH)
|
|
||||||
) axis_status_read (
|
|
||||||
.aclk(ctrl_clk),
|
|
||||||
.aresetn(rst_n)
|
|
||||||
);
|
|
||||||
|
|
||||||
axis_if #(
|
|
||||||
.DATA_W(WRITE_STATUS_WIDTH),
|
|
||||||
.KEEP_W(WRITE_STATUS_KEEP_W),
|
|
||||||
.ID_W(AXIS_ID_WIDTH),
|
|
||||||
.DEST_W(AXIS_DEST_WIDTH),
|
|
||||||
.USER_W(AXIS_USER_WIDTH)
|
|
||||||
) axis_status_write (
|
|
||||||
.aclk(ctrl_clk),
|
|
||||||
.aresetn(rst_n)
|
|
||||||
);
|
|
||||||
|
|
||||||
axis_if #(
|
|
||||||
.DATA_W(READ_DESC_WIDTH),
|
|
||||||
.KEEP_W(READ_DESC_KEEP_W),
|
|
||||||
.ID_W(AXIS_ID_WIDTH),
|
|
||||||
.DEST_W(AXIS_DEST_WIDTH),
|
|
||||||
.USER_W(AXIS_USER_WIDTH)
|
|
||||||
) axis_desc_read (
|
|
||||||
.aclk(ctrl_clk),
|
|
||||||
.aresetn(rst_n)
|
|
||||||
);
|
|
||||||
|
|
||||||
axis_if #(
|
|
||||||
.DATA_W(WRITE_DESC_WIDTH),
|
|
||||||
.KEEP_W(WRITE_DESC_KEEP_W),
|
|
||||||
.ID_W(AXIS_ID_WIDTH),
|
|
||||||
.DEST_W(AXIS_DEST_WIDTH),
|
|
||||||
.USER_W(AXIS_USER_WIDTH)
|
|
||||||
) axis_desc_write (
|
|
||||||
.aclk(ctrl_clk),
|
|
||||||
.aresetn(rst_n)
|
|
||||||
);
|
|
||||||
|
|
||||||
// testbench flat status -> DUT AXIS slave ports
|
|
||||||
axis_flat_to_if #(
|
|
||||||
.DATA_W(READ_STATUS_WIDTH),
|
|
||||||
.KEEP_W(READ_STATUS_KEEP_W),
|
|
||||||
.ID_W(AXIS_ID_WIDTH),
|
|
||||||
.DEST_W(AXIS_DEST_WIDTH),
|
|
||||||
.USER_W(AXIS_USER_WIDTH)
|
|
||||||
) u_status_read_flat_to_if (
|
|
||||||
.s_axis_tdata (status_read_cmd_in),
|
|
||||||
.s_axis_tkeep ({READ_STATUS_KEEP_W{1'b1}}),
|
|
||||||
.s_axis_tstrb ({READ_STATUS_KEEP_W{1'b1}}),
|
|
||||||
.s_axis_tlast (1'b1),
|
|
||||||
.s_axis_tid ('0),
|
|
||||||
.s_axis_tdest ('0),
|
|
||||||
.s_axis_tuser ('0),
|
|
||||||
.s_axis_tvalid(valid_status_read),
|
|
||||||
.s_axis_tready(ready_status_read),
|
|
||||||
|
|
||||||
.m_axis(axis_status_read)
|
|
||||||
);
|
|
||||||
|
|
||||||
axis_flat_to_if #(
|
|
||||||
.DATA_W(WRITE_STATUS_WIDTH),
|
|
||||||
.KEEP_W(WRITE_STATUS_KEEP_W),
|
|
||||||
.ID_W(AXIS_ID_WIDTH),
|
|
||||||
.DEST_W(AXIS_DEST_WIDTH),
|
|
||||||
.USER_W(AXIS_USER_WIDTH)
|
|
||||||
) u_status_write_flat_to_if (
|
|
||||||
.s_axis_tdata (status_write_cmd_in),
|
|
||||||
.s_axis_tkeep ({WRITE_STATUS_KEEP_W{1'b1}}),
|
|
||||||
.s_axis_tstrb ({WRITE_STATUS_KEEP_W{1'b1}}),
|
|
||||||
.s_axis_tlast (1'b1),
|
|
||||||
.s_axis_tid ('0),
|
|
||||||
.s_axis_tdest ('0),
|
|
||||||
.s_axis_tuser ('0),
|
|
||||||
.s_axis_tvalid(valid_status_write),
|
|
||||||
.s_axis_tready(ready_status_write),
|
|
||||||
|
|
||||||
.m_axis(axis_status_write)
|
|
||||||
);
|
|
||||||
|
|
||||||
// DUT AXIS master ports -> testbench flat descriptor outputs
|
|
||||||
logic [READ_DESC_KEEP_W-1:0] unused_desc_read_tkeep;
|
|
||||||
logic [READ_DESC_KEEP_W-1:0] unused_desc_read_tstrb;
|
|
||||||
logic unused_desc_read_tlast;
|
|
||||||
logic [AXIS_ID_WIDTH-1:0] unused_desc_read_tid;
|
|
||||||
logic [AXIS_DEST_WIDTH-1:0] unused_desc_read_tdest;
|
|
||||||
logic [AXIS_USER_WIDTH-1:0] unused_desc_read_tuser;
|
|
||||||
|
|
||||||
axis_if_to_flat #(
|
|
||||||
.DATA_W(READ_DESC_WIDTH),
|
|
||||||
.KEEP_W(READ_DESC_KEEP_W),
|
|
||||||
.ID_W(AXIS_ID_WIDTH),
|
|
||||||
.DEST_W(AXIS_DEST_WIDTH),
|
|
||||||
.USER_W(AXIS_USER_WIDTH)
|
|
||||||
) u_desc_read_if_to_flat (
|
|
||||||
.s_axis(axis_desc_read),
|
|
||||||
|
|
||||||
.m_axis_tdata (desc_read_cmd_out),
|
|
||||||
.m_axis_tkeep (unused_desc_read_tkeep),
|
|
||||||
.m_axis_tstrb (unused_desc_read_tstrb),
|
|
||||||
.m_axis_tlast (unused_desc_read_tlast),
|
|
||||||
.m_axis_tid (unused_desc_read_tid),
|
|
||||||
.m_axis_tdest (unused_desc_read_tdest),
|
|
||||||
.m_axis_tuser (unused_desc_read_tuser),
|
|
||||||
.m_axis_tvalid(valid_desc_read),
|
|
||||||
.m_axis_tready(ready_desc_read)
|
|
||||||
);
|
|
||||||
|
|
||||||
logic [WRITE_DESC_KEEP_W-1:0] unused_desc_write_tkeep;
|
|
||||||
logic [WRITE_DESC_KEEP_W-1:0] unused_desc_write_tstrb;
|
|
||||||
logic unused_desc_write_tlast;
|
|
||||||
logic [AXIS_ID_WIDTH-1:0] unused_desc_write_tid;
|
|
||||||
logic [AXIS_DEST_WIDTH-1:0] unused_desc_write_tdest;
|
|
||||||
logic [AXIS_USER_WIDTH-1:0] unused_desc_write_tuser;
|
|
||||||
|
|
||||||
axis_if_to_flat #(
|
|
||||||
.DATA_W(WRITE_DESC_WIDTH),
|
|
||||||
.KEEP_W(WRITE_DESC_KEEP_W),
|
|
||||||
.ID_W(AXIS_ID_WIDTH),
|
|
||||||
.DEST_W(AXIS_DEST_WIDTH),
|
|
||||||
.USER_W(AXIS_USER_WIDTH)
|
|
||||||
) u_desc_write_if_to_flat (
|
|
||||||
.s_axis(axis_desc_write),
|
|
||||||
|
|
||||||
.m_axis_tdata (desc_write_cmd_out),
|
|
||||||
.m_axis_tkeep (unused_desc_write_tkeep),
|
|
||||||
.m_axis_tstrb (unused_desc_write_tstrb),
|
|
||||||
.m_axis_tlast (unused_desc_write_tlast),
|
|
||||||
.m_axis_tid (unused_desc_write_tid),
|
|
||||||
.m_axis_tdest (unused_desc_write_tdest),
|
|
||||||
.m_axis_tuser (unused_desc_write_tuser),
|
|
||||||
.m_axis_tvalid(valid_desc_write),
|
|
||||||
.m_axis_tready(ready_desc_write)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Controller ADC/DAC outputs.
|
|
||||||
logic [31:0] adc_window_size;
|
|
||||||
logic [31:0] dac_pulse_width;
|
|
||||||
logic [31:0] dac_pulse_period;
|
|
||||||
logic [DAC_DATA_WIDTH-1:0] dac_pulse_height;
|
|
||||||
logic [15:0] dac_pulse_num;
|
|
||||||
logic [31:0] adc_pulse_period;
|
|
||||||
logic [15:0] adc_pulse_num;
|
|
||||||
logic dac_start;
|
|
||||||
logic adc_start;
|
|
||||||
logic dac_rst;
|
|
||||||
logic adc_rst;
|
|
||||||
|
|
||||||
controller_wrapper_axil #(
|
|
||||||
.ADDR_W(ADDR_W),
|
|
||||||
.DATA_W(DATA_W),
|
|
||||||
.USER_W(USER_W),
|
|
||||||
.DAC_DATA_WIDTH(DAC_DATA_WIDTH),
|
|
||||||
.AXI_ADDR_WIDTH(AXI_ADDR_WIDTH),
|
|
||||||
.AXIS_ID_WIDTH(AXIS_ID_WIDTH),
|
|
||||||
.LEN_WIDTH(LEN_WIDTH),
|
|
||||||
.AXIS_USER_WIDTH(AXIS_USER_WIDTH),
|
|
||||||
.AXIS_DEST_WIDTH(AXIS_DEST_WIDTH),
|
|
||||||
.TAG_WIDTH(TAG_WIDTH),
|
|
||||||
.READ_DESC_WIDTH(READ_DESC_WIDTH),
|
|
||||||
.WRITE_DESC_WIDTH(WRITE_DESC_WIDTH),
|
|
||||||
.READ_STATUS_WIDTH(READ_STATUS_WIDTH),
|
|
||||||
.WRITE_STATUS_WIDTH(WRITE_STATUS_WIDTH)
|
|
||||||
) dut (
|
|
||||||
.ctrl_clk(ctrl_clk),
|
|
||||||
.dac_clk_in(dac_clk_in),
|
|
||||||
.adc_clk_in(adc_clk_in),
|
|
||||||
.rst_n(rst_n),
|
|
||||||
.s_axil(axil_bus),
|
|
||||||
|
|
||||||
.finish(finish),
|
|
||||||
.adc_window_size(adc_window_size),
|
|
||||||
|
|
||||||
.dac_pulse_width(dac_pulse_width),
|
|
||||||
.dac_pulse_period(dac_pulse_period),
|
|
||||||
.dac_pulse_height(dac_pulse_height),
|
|
||||||
.dac_pulse_num(dac_pulse_num),
|
|
||||||
|
|
||||||
.adc_pulse_period(adc_pulse_period),
|
|
||||||
.adc_pulse_num(adc_pulse_num),
|
|
||||||
|
|
||||||
.dac_start(dac_start),
|
|
||||||
.adc_start(adc_start),
|
|
||||||
.dac_rst(dac_rst),
|
|
||||||
.adc_rst(adc_rst),
|
|
||||||
|
|
||||||
.s_axis_status_read(axis_status_read),
|
|
||||||
.s_axis_status_write(axis_status_write),
|
|
||||||
|
|
||||||
.m_axis_desc_read(axis_desc_read),
|
|
||||||
.m_axis_desc_write(axis_desc_write)
|
|
||||||
);
|
|
||||||
|
|
||||||
endmodule : tb_controller_wrapper_axil
|
|
||||||
@@ -1,170 +0,0 @@
|
|||||||
import cocotb
|
|
||||||
from cocotb.clock import Clock
|
|
||||||
from cocotb.handle import Immediate
|
|
||||||
from cocotb.triggers import RisingEdge
|
|
||||||
from cocotbext.axi import AxiLiteBus, AxiLiteMaster
|
|
||||||
|
|
||||||
|
|
||||||
# Register indexes from axi4l_reg_map_controller_pkg.sv
|
|
||||||
REG_CONTROL = 0
|
|
||||||
REG_STATUS = 1
|
|
||||||
REG_DAC_WIDTH = 2
|
|
||||||
REG_DAC_PERIOD = 3
|
|
||||||
REG_DAC_PULSE_NUM = 4
|
|
||||||
REG_DAC_PULSE_HEIGHT = 5
|
|
||||||
REG_ADC_PERIOD = 6
|
|
||||||
REG_WINDOW_SIZE = 7
|
|
||||||
REG_ERROR = 8
|
|
||||||
REG_DESC_READ_ADDR = 9
|
|
||||||
REG_DESC_READ_LEN = 10
|
|
||||||
REG_DESC_READ_CONFIG = 11
|
|
||||||
REG_READ_STATUS = 12
|
|
||||||
REG_DESC_WRITE_ADDR = 13
|
|
||||||
REG_DESC_WRITE_LEN_AND_TAG = 14
|
|
||||||
REG_STATUS_WRITE_LEN = 15
|
|
||||||
REG_STATUS_WRITE_CONFIG = 16
|
|
||||||
|
|
||||||
|
|
||||||
# REG_CONTROL pulse bits
|
|
||||||
CTRL_START = 0
|
|
||||||
CTRL_RST_SOFT = 1
|
|
||||||
CTRL_CFG_BUS_VALID = 2
|
|
||||||
CTRL_SEND_DESC_READ = 3
|
|
||||||
CTRL_SEND_DESC_WRITE = 4
|
|
||||||
CTRL_TAKE_STATUS_READ = 5
|
|
||||||
CTRL_TAKE_STATUS_WRITE = 6
|
|
||||||
|
|
||||||
|
|
||||||
def reg_addr(reg_index: int) -> int:
|
|
||||||
# AXI-Lite uses byte addresses, 32-bit registers are spaced by 4 bytes.
|
|
||||||
return reg_index * 4
|
|
||||||
|
|
||||||
|
|
||||||
def u32(value: int) -> bytes:
|
|
||||||
return int(value & 0xFFFFFFFF).to_bytes(4, "little")
|
|
||||||
|
|
||||||
|
|
||||||
class TB:
|
|
||||||
def __init__(self, dut):
|
|
||||||
self.dut = dut
|
|
||||||
|
|
||||||
cocotb.start_soon(Clock(dut.ctrl_clk, 10, units="ns").start())
|
|
||||||
|
|
||||||
self.axil = AxiLiteMaster(
|
|
||||||
AxiLiteBus.from_prefix(dut, "s_axil"),
|
|
||||||
dut.ctrl_clk,
|
|
||||||
dut.rst,
|
|
||||||
)
|
|
||||||
|
|
||||||
async def reset(self):
|
|
||||||
self.dut.rst.value = 1
|
|
||||||
for _ in range(5):
|
|
||||||
await RisingEdge(self.dut.ctrl_clk)
|
|
||||||
|
|
||||||
self.dut.rst.value = 0
|
|
||||||
for _ in range(5):
|
|
||||||
await RisingEdge(self.dut.ctrl_clk)
|
|
||||||
|
|
||||||
async def write_reg(self, reg_index: int, value: int):
|
|
||||||
await self.axil.write(reg_addr(reg_index), u32(value))
|
|
||||||
|
|
||||||
async def read_reg(self, reg_index: int) -> int:
|
|
||||||
resp = await self.axil.read(reg_addr(reg_index), 4)
|
|
||||||
return int.from_bytes(bytes(resp.data), "little")
|
|
||||||
|
|
||||||
|
|
||||||
@cocotb.test()
|
|
||||||
async def simple_axil_write_read(dut):
|
|
||||||
tb = TB(dut)
|
|
||||||
await tb.reset()
|
|
||||||
|
|
||||||
await tb.write_reg(REG_DAC_WIDTH, 0x0000_0123)
|
|
||||||
|
|
||||||
value = await tb.read_reg(REG_DAC_WIDTH)
|
|
||||||
assert value == 0x0000_0123
|
|
||||||
|
|
||||||
|
|
||||||
@cocotb.test()
|
|
||||||
async def simple_controller_config_write(dut):
|
|
||||||
tb = TB(dut)
|
|
||||||
await tb.reset()
|
|
||||||
|
|
||||||
await tb.write_reg(REG_DAC_WIDTH, 0x10)
|
|
||||||
await tb.write_reg(REG_DAC_PERIOD, 0x40)
|
|
||||||
await tb.write_reg(REG_DAC_PULSE_NUM, 3)
|
|
||||||
await tb.write_reg(REG_DAC_PULSE_HEIGHT, 0x7FF)
|
|
||||||
await tb.write_reg(REG_ADC_PERIOD, 0x80)
|
|
||||||
await tb.write_reg(REG_WINDOW_SIZE, 16)
|
|
||||||
|
|
||||||
assert await tb.read_reg(REG_DAC_WIDTH) == 0x10
|
|
||||||
assert await tb.read_reg(REG_WINDOW_SIZE) == 16
|
|
||||||
|
|
||||||
# write data: set cfg_bus_valid signal
|
|
||||||
await tb.write_reg(REG_CONTROL, 1 << CTRL_CFG_BUS_VALID)
|
|
||||||
|
|
||||||
# wait
|
|
||||||
for _ in range(30):
|
|
||||||
await RisingEdge(dut.ctrl_clk)
|
|
||||||
|
|
||||||
# check config
|
|
||||||
assert int(dut.dac_pulse_width) == 0x10
|
|
||||||
assert int(dut.dac_pulse_period) == 0x40
|
|
||||||
assert int(dut.dac_pulse_num) == 3
|
|
||||||
assert int(dut.dac_pulse_height) == 0x7FF
|
|
||||||
assert int(dut.adc_pulse_period) == 0x80
|
|
||||||
assert int(dut.adc_window_size) == 16
|
|
||||||
|
|
||||||
await RisingEdge(dut.ctrl_clk)
|
|
||||||
|
|
||||||
|
|
||||||
@cocotb.test()
|
|
||||||
async def simple_controller_start_check(dut):
|
|
||||||
tb = TB(dut)
|
|
||||||
await tb.reset()
|
|
||||||
await tb.write_reg(REG_CONTROL, 1 << CTRL_START)
|
|
||||||
|
|
||||||
await RisingEdge(dut.dac_start)
|
|
||||||
|
|
||||||
|
|
||||||
@cocotb.test()
|
|
||||||
async def simple_dma_desc_status(dut):
|
|
||||||
tb = TB(dut)
|
|
||||||
await tb.reset()
|
|
||||||
|
|
||||||
await tb.write_reg(REG_DESC_READ_ADDR, 0xdead)
|
|
||||||
await tb.write_reg(REG_DESC_READ_LEN, 64)
|
|
||||||
await tb.write_reg(REG_DESC_READ_CONFIG, 0x0000_0001)
|
|
||||||
|
|
||||||
await tb.write_reg(REG_DESC_WRITE_ADDR, 0xbeef)
|
|
||||||
await tb.write_reg(REG_DESC_WRITE_LEN_AND_TAG, 0x0005555)
|
|
||||||
|
|
||||||
# W1S pulse: bit 3 = send_desc_read_o.
|
|
||||||
await tb.write_reg(REG_CONTROL, 1 << CTRL_SEND_DESC_READ)
|
|
||||||
|
|
||||||
await tb.write_reg(REG_CONTROL, 1 << CTRL_SEND_DESC_WRITE)
|
|
||||||
|
|
||||||
for _ in range(20):
|
|
||||||
await RisingEdge(dut.ctrl_clk)
|
|
||||||
|
|
||||||
assert int(dut.desc_read_cmd_out.value) == 0x000000100040DEAD
|
|
||||||
assert int(dut.desc_write_cmd_out.value) == 0x0005555BEEF
|
|
||||||
|
|
||||||
# test status
|
|
||||||
dut.status_read_cmd_in.value = Immediate(123)
|
|
||||||
dut.status_write_cmd_in.value = Immediate(0xabcd90012345)
|
|
||||||
dut.valid_status_read.value = Immediate(1)
|
|
||||||
dut.valid_status_write.value = Immediate(1)
|
|
||||||
|
|
||||||
for _ in range(10):
|
|
||||||
await RisingEdge(dut.ctrl_clk)
|
|
||||||
|
|
||||||
# read status
|
|
||||||
await tb.write_reg(REG_CONTROL, 1 << CTRL_TAKE_STATUS_READ)
|
|
||||||
await tb.write_reg(REG_CONTROL, 1 << CTRL_TAKE_STATUS_WRITE)
|
|
||||||
|
|
||||||
for _ in range(10):
|
|
||||||
await RisingEdge(dut.ctrl_clk)
|
|
||||||
|
|
||||||
assert await tb.read_reg(REG_READ_STATUS) == 123
|
|
||||||
assert await tb.read_reg(REG_STATUS_WRITE_CONFIG) == 0xABCD900
|
|
||||||
assert await tb.read_reg(REG_STATUS_WRITE_LEN) == 0x12345
|
|
||||||
+133
-19
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
import math
|
import math
|
||||||
|
import json
|
||||||
import socket
|
import socket
|
||||||
import platform
|
import platform
|
||||||
|
|
||||||
@@ -14,6 +15,19 @@ from PyQt6.QtCore import Qt
|
|||||||
import pyqtgraph as pg
|
import pyqtgraph as pg
|
||||||
from PyQt6.QtWidgets import QApplication, QMainWindow
|
from PyQt6.QtWidgets import QApplication, QMainWindow
|
||||||
|
|
||||||
|
SETTINGS_LIST = [
|
||||||
|
"dac_dw",
|
||||||
|
"adc_dw",
|
||||||
|
"nmax",
|
||||||
|
"window_size",
|
||||||
|
"packet_size",
|
||||||
|
"adc_clk",
|
||||||
|
"dac_clk",
|
||||||
|
"accum_width",
|
||||||
|
"recv_port",
|
||||||
|
"send_port",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ReflectometerConfig:
|
class ReflectometerConfig:
|
||||||
@@ -31,7 +45,9 @@ class ReflectometerConfig:
|
|||||||
pulse_height: int
|
pulse_height: int
|
||||||
pulse_num: int
|
pulse_num: int
|
||||||
|
|
||||||
adc_dac_ratio: float = 0.52
|
# adc_dac_ratio: float = 0.52
|
||||||
|
adc_clk: float = 65
|
||||||
|
dac_clk: float = 125
|
||||||
socket_timeout_sec: float = 2.0
|
socket_timeout_sec: float = 2.0
|
||||||
|
|
||||||
|
|
||||||
@@ -46,6 +62,7 @@ class ReflectometerWorker(QObject):
|
|||||||
self.config = config
|
self.config = config
|
||||||
self._stop_requested = False
|
self._stop_requested = False
|
||||||
self._sock = None
|
self._sock = None
|
||||||
|
self.measure_timeout = 1.0
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self._stop_requested = True
|
self._stop_requested = True
|
||||||
@@ -64,7 +81,7 @@ class ReflectometerWorker(QObject):
|
|||||||
|
|
||||||
self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
self._sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
self._sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||||
self._sock.settimeout(self.config.socket_timeout_sec)
|
self._sock.settimeout(self.measure_timeout)
|
||||||
self._sock.bind(("0.0.0.0", self.config.recv_port))
|
self._sock.bind(("0.0.0.0", self.config.recv_port))
|
||||||
|
|
||||||
dest = (self.config.ip, self.config.send_port)
|
dest = (self.config.ip, self.config.send_port)
|
||||||
@@ -108,7 +125,8 @@ class ReflectometerWorker(QObject):
|
|||||||
output += 0b10001000.to_bytes(1, "little")
|
output += 0b10001000.to_bytes(1, "little")
|
||||||
|
|
||||||
pulse_period_adc = (
|
pulse_period_adc = (
|
||||||
int(self.config.pulse_period * self.config.adc_dac_ratio)
|
int(self.config.pulse_period *
|
||||||
|
(self.config.adc_clk / self.config.dac_clk))
|
||||||
// self.config.window_size
|
// self.config.window_size
|
||||||
) * self.config.window_size
|
) * self.config.window_size
|
||||||
|
|
||||||
@@ -126,7 +144,7 @@ class ReflectometerWorker(QObject):
|
|||||||
def _recv_data(self) -> list[int]:
|
def _recv_data(self) -> list[int]:
|
||||||
packet_count = math.ceil(
|
packet_count = math.ceil(
|
||||||
(
|
(
|
||||||
self.config.adc_dac_ratio
|
(self.config.adc_clk / self.config.dac_clk)
|
||||||
* self.config.pulse_period
|
* self.config.pulse_period
|
||||||
/ self.config.window_size
|
/ self.config.window_size
|
||||||
* self.config.data_width
|
* self.config.data_width
|
||||||
@@ -135,7 +153,7 @@ class ReflectometerWorker(QObject):
|
|||||||
)
|
)
|
||||||
|
|
||||||
expected_length = math.ceil(
|
expected_length = math.ceil(
|
||||||
self.config.adc_dac_ratio
|
(self.config.adc_clk / self.config.dac_clk)
|
||||||
* self.config.pulse_period
|
* self.config.pulse_period
|
||||||
/ self.config.window_size
|
/ self.config.window_size
|
||||||
)
|
)
|
||||||
@@ -227,7 +245,6 @@ class MainWindow(QMainWindow):
|
|||||||
self.nmax = 4096
|
self.nmax = 4096
|
||||||
self.packet_size = 1024
|
self.packet_size = 1024
|
||||||
self.window_size = 65
|
self.window_size = 65
|
||||||
self.adc_dac_ration = 0.52
|
|
||||||
self.accum_width = 32
|
self.accum_width = 32
|
||||||
|
|
||||||
# setup
|
# setup
|
||||||
@@ -239,8 +256,6 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
self.data = []
|
self.data = []
|
||||||
|
|
||||||
self.adc_dac_ratio = 0.52
|
|
||||||
|
|
||||||
self.measurement_thread = None
|
self.measurement_thread = None
|
||||||
self.measurement_worker = None
|
self.measurement_worker = None
|
||||||
|
|
||||||
@@ -250,8 +265,58 @@ class MainWindow(QMainWindow):
|
|||||||
self.button_start.clicked.connect(self.run_measurement)
|
self.button_start.clicked.connect(self.run_measurement)
|
||||||
self.button_graph_autoscale.clicked.connect(self.reset_graph_autoscale)
|
self.button_graph_autoscale.clicked.connect(self.reset_graph_autoscale)
|
||||||
|
|
||||||
# ping utils
|
self.button_save.clicked.connect(self.save_config)
|
||||||
|
self.button_load.clicked.connect(self.load_config)
|
||||||
|
|
||||||
|
# timeout progress bar
|
||||||
|
self.measure_progress_timer = QTimer(self)
|
||||||
|
self.measure_progress_timer.setInterval(50)
|
||||||
|
self.measure_progress_timer.timeout.connect(
|
||||||
|
self.update_measure_progress)
|
||||||
|
|
||||||
|
self.measure_progress_elapsed_ms = 0
|
||||||
|
self.measure_progress_total_ms = 1
|
||||||
|
|
||||||
|
self.progress_measure.setRange(0, 100)
|
||||||
|
self.progress_measure.setValue(0)
|
||||||
|
|
||||||
|
def update_measure_progress(self):
|
||||||
|
self.measure_progress_elapsed_ms += self.measure_progress_timer.interval()
|
||||||
|
|
||||||
|
progress = int(
|
||||||
|
self.measure_progress_elapsed_ms
|
||||||
|
/ self.measure_progress_total_ms
|
||||||
|
* 100
|
||||||
|
)
|
||||||
|
|
||||||
|
self.progress_measure.setValue(min(progress, 100))
|
||||||
|
|
||||||
|
if progress >= 100:
|
||||||
|
self.measure_progress_timer.stop()
|
||||||
|
|
||||||
|
# load/save
|
||||||
|
|
||||||
|
def save_config(self):
|
||||||
|
|
||||||
|
conf = {}
|
||||||
|
for setting in SETTINGS_LIST:
|
||||||
|
conf[setting] = self.__getattribute__(setting)
|
||||||
|
with open(".settings.json", "w") as f:
|
||||||
|
f.write(json.dumps(conf))
|
||||||
|
self.label_save_status.setText("Настройки сохранены")
|
||||||
|
|
||||||
|
def load_config(self):
|
||||||
|
try:
|
||||||
|
with open(".settings.json", 'r') as f:
|
||||||
|
conf = json.loads(f.read())
|
||||||
|
except FileNotFoundError:
|
||||||
|
self.label_save_status.setText("Нет сохранненого .setting.json")
|
||||||
|
return
|
||||||
|
for setting in conf:
|
||||||
|
self.__getattribute__(f"box_{setting}").setValue(conf[setting])
|
||||||
|
self.label_save_status.setText("Настройки загружены")
|
||||||
|
|
||||||
|
# ping utils
|
||||||
def check_ping(self):
|
def check_ping(self):
|
||||||
ip = self.line_ip.text().strip()
|
ip = self.line_ip.text().strip()
|
||||||
|
|
||||||
@@ -280,14 +345,14 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
if system_name == "windows":
|
if system_name == "windows":
|
||||||
program = "ping"
|
program = "ping"
|
||||||
arguments = ["-n", "1", "-w", "2000", ip]
|
arguments = ["-n", "1", "-w", "1000", ip]
|
||||||
else:
|
else:
|
||||||
program = "ping"
|
program = "ping"
|
||||||
arguments = ["-c", "1", "-W", "2", ip]
|
arguments = ["-c", "1", "-W", "1", ip]
|
||||||
|
|
||||||
self.ping_process.start(program, arguments)
|
self.ping_process.start(program, arguments)
|
||||||
# fallback
|
# fallback
|
||||||
self.ping_timeout_timer.start(2000)
|
self.ping_timeout_timer.start(1000)
|
||||||
|
|
||||||
def on_ping_finished(self, exit_code, exit_status):
|
def on_ping_finished(self, exit_code, exit_status):
|
||||||
self.ping_timeout_timer.stop()
|
self.ping_timeout_timer.stop()
|
||||||
@@ -371,6 +436,7 @@ class MainWindow(QMainWindow):
|
|||||||
box.setValue(new_value)
|
box.setValue(new_value)
|
||||||
|
|
||||||
setattr(self, name, new_value)
|
setattr(self, name, new_value)
|
||||||
|
self.recalculate_times()
|
||||||
|
|
||||||
slider.valueChanged.connect(update_value)
|
slider.valueChanged.connect(update_value)
|
||||||
box.valueChanged.connect(update_value)
|
box.valueChanged.connect(update_value)
|
||||||
@@ -426,6 +492,22 @@ class MainWindow(QMainWindow):
|
|||||||
)
|
)
|
||||||
self.pulse_num = self.box_pulse_num.value()
|
self.pulse_num = self.box_pulse_num.value()
|
||||||
|
|
||||||
|
def recalculate_times(self):
|
||||||
|
# пересчет показываемых метрик
|
||||||
|
LS = 200000 # ~km/s
|
||||||
|
period_us = (self.pulse_period / self.dac_clk)
|
||||||
|
self.label_meas_time.setText(
|
||||||
|
f"{round(period_us, 1)}мкс / {round(LS * period_us / 10e6, 1)}км")
|
||||||
|
|
||||||
|
self.label_duty.setText(
|
||||||
|
f"{round(self.pulse_width / self.pulse_period * 100, 4)}%")
|
||||||
|
|
||||||
|
self.label_voltage.setText(
|
||||||
|
f"{round((self.pulse_height - 8192) * 10 / 16384, 3)}V")
|
||||||
|
|
||||||
|
self.label_meas_total.setText(
|
||||||
|
f"{round(period_us * self.pulse_num / 10e6, 3)}с")
|
||||||
|
|
||||||
# settings
|
# settings
|
||||||
|
|
||||||
def setup_global_settings(self):
|
def setup_global_settings(self):
|
||||||
@@ -456,8 +538,13 @@ class MainWindow(QMainWindow):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self._bind_spinbox_setting(
|
self._bind_spinbox_setting(
|
||||||
name="adc_dac_ratio",
|
name="adc_clk",
|
||||||
box=self.box_adc_dac_ratio,
|
box=self.box_adc_clk,
|
||||||
|
)
|
||||||
|
|
||||||
|
self._bind_spinbox_setting(
|
||||||
|
name="dac_clk",
|
||||||
|
box=self.box_dac_clk,
|
||||||
)
|
)
|
||||||
|
|
||||||
self._bind_spinbox_setting(
|
self._bind_spinbox_setting(
|
||||||
@@ -554,7 +641,7 @@ class MainWindow(QMainWindow):
|
|||||||
def setup_graph(self):
|
def setup_graph(self):
|
||||||
self.graph_widget = pg.PlotWidget()
|
self.graph_widget = pg.PlotWidget()
|
||||||
self.graph_widget.setLabel("left", "ADC value")
|
self.graph_widget.setLabel("left", "ADC value")
|
||||||
self.graph_widget.setLabel("bottom", "Sample")
|
self.graph_widget.setLabel("bottom", "Distance", units="km")
|
||||||
self.graph_widget.showGrid(x=True, y=True)
|
self.graph_widget.showGrid(x=True, y=True)
|
||||||
|
|
||||||
self.graph_curve = self.graph_widget.plot(
|
self.graph_curve = self.graph_widget.plot(
|
||||||
@@ -596,10 +683,21 @@ class MainWindow(QMainWindow):
|
|||||||
config = self.build_reflectometer_config()
|
config = self.build_reflectometer_config()
|
||||||
|
|
||||||
self.data = []
|
self.data = []
|
||||||
self.graph_curve.setData([])
|
|
||||||
|
# self.graph_curve.setData([])
|
||||||
|
|
||||||
self.measurement_thread = QThread(self)
|
self.measurement_thread = QThread(self)
|
||||||
self.measurement_worker = ReflectometerWorker(config)
|
self.measurement_worker = ReflectometerWorker(config)
|
||||||
|
period_us = (self.pulse_period / self.dac_clk)
|
||||||
|
self.measurement_worker.measure_timeout = period_us * self.pulse_num / 10e6 + 0.2
|
||||||
|
|
||||||
|
self.measure_progress_total_ms = int(
|
||||||
|
self.measurement_worker.measure_timeout * 1000 - 199
|
||||||
|
)
|
||||||
|
self.measure_progress_elapsed_ms = 0
|
||||||
|
|
||||||
|
self.progress_measure.setValue(0)
|
||||||
|
self.measure_progress_timer.start()
|
||||||
|
|
||||||
self.measurement_worker.moveToThread(self.measurement_thread)
|
self.measurement_worker.moveToThread(self.measurement_thread)
|
||||||
|
|
||||||
@@ -642,7 +740,8 @@ class MainWindow(QMainWindow):
|
|||||||
pulse_height=self.pulse_height,
|
pulse_height=self.pulse_height,
|
||||||
pulse_num=self.pulse_num,
|
pulse_num=self.pulse_num,
|
||||||
|
|
||||||
adc_dac_ratio=self.adc_dac_ratio,
|
adc_clk=self.adc_clk,
|
||||||
|
dac_clk=self.dac_clk
|
||||||
)
|
)
|
||||||
|
|
||||||
def on_data_received(self, data: list[int]):
|
def on_data_received(self, data: list[int]):
|
||||||
@@ -664,10 +763,14 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
def on_measurement_error(self, message: str):
|
def on_measurement_error(self, message: str):
|
||||||
self.set_measurement_status(f"Ошибка: {message}")
|
self.set_measurement_status(f"Ошибка: {message}")
|
||||||
|
if self.checkbox_autorestart.isChecked():
|
||||||
|
self.run_measurement()
|
||||||
|
|
||||||
def on_measurement_finished(self):
|
def on_measurement_finished(self):
|
||||||
self.measurement_worker = None
|
self.measurement_worker = None
|
||||||
self.measurement_thread = None
|
self.measurement_thread = None
|
||||||
|
if self.checkbox_autorestart.isChecked():
|
||||||
|
self.run_measurement()
|
||||||
|
|
||||||
def stop_measurement(self):
|
def stop_measurement(self):
|
||||||
if self.measurement_worker is not None:
|
if self.measurement_worker is not None:
|
||||||
@@ -681,7 +784,18 @@ class MainWindow(QMainWindow):
|
|||||||
self.graph_curve.setData([])
|
self.graph_curve.setData([])
|
||||||
return
|
return
|
||||||
|
|
||||||
x = list(range(len(self.data)))
|
LS = 200000 # km/s
|
||||||
|
|
||||||
|
period_us = self.pulse_period / self.dac_clk
|
||||||
|
max_distance_km = LS * period_us / 10e6
|
||||||
|
|
||||||
|
sample_count = len(self.data)
|
||||||
|
|
||||||
|
x = [
|
||||||
|
i * max_distance_km / sample_count
|
||||||
|
for i in range(sample_count)
|
||||||
|
]
|
||||||
|
|
||||||
self.graph_curve.setData(x, self.data)
|
self.graph_curve.setData(x, self.data)
|
||||||
|
|
||||||
def update_reference_graph(self):
|
def update_reference_graph(self):
|
||||||
@@ -711,7 +825,7 @@ class MainWindow(QMainWindow):
|
|||||||
reference = [0] * length
|
reference = [0] * length
|
||||||
|
|
||||||
actual_pulse_width = round(
|
actual_pulse_width = round(
|
||||||
(self.pulse_width * self.adc_dac_ratio) / self.window_size)
|
(self.pulse_width * self.adc_clk / self.dac_clk) / self.window_size)
|
||||||
|
|
||||||
reference[0:actual_pulse_width] = [
|
reference[0:actual_pulse_width] = [
|
||||||
(self.pulse_height / 2 ** (self.dac_dw - self.adc_dw)) - 2 ** (self.adc_dw - 1), ] * (actual_pulse_width - 1)
|
(self.pulse_height / 2 ** (self.dac_dw - self.adc_dw)) - 2 ** (self.adc_dw - 1), ] * (actual_pulse_width - 1)
|
||||||
|
|||||||
+158
-12
@@ -7,11 +7,11 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>1023</width>
|
<width>1023</width>
|
||||||
<height>708</height>
|
<height>844</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Reflectometer PREMIUM</string>
|
<string>Reflectometer PRO MAX</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="centralwidget">
|
<widget class="QWidget" name="centralwidget">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="4,2">
|
<layout class="QHBoxLayout" name="horizontalLayout" stretch="4,2">
|
||||||
@@ -39,9 +39,9 @@
|
|||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>-32</y>
|
||||||
<width>294</width>
|
<width>294</width>
|
||||||
<height>621</height>
|
<height>762</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
@@ -118,21 +118,37 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QDoubleSpinBox" name="box_adc_dac_ratio">
|
<widget class="QSpinBox" name="box_adc_clk">
|
||||||
|
<property name="suffix">
|
||||||
|
<string> MHz</string>
|
||||||
|
</property>
|
||||||
<property name="prefix">
|
<property name="prefix">
|
||||||
<string>ADC:DAC clk ratio: </string>
|
<string>ADC CLK: </string>
|
||||||
</property>
|
</property>
|
||||||
<property name="minimum">
|
<property name="minimum">
|
||||||
<double>0.200000000000000</double>
|
<number>25</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="maximum">
|
<property name="maximum">
|
||||||
<double>3.000000000000000</double>
|
<number>350</number>
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<double>0.010000000000000</double>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="value">
|
<property name="value">
|
||||||
<double>0.520000000000000</double>
|
<number>65</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="box_dac_clk">
|
||||||
|
<property name="suffix">
|
||||||
|
<string> MHz</string>
|
||||||
|
</property>
|
||||||
|
<property name="prefix">
|
||||||
|
<string>DAC CLK: </string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>25</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>350</number>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -292,6 +308,50 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="Line" name="line">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Orientation::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_12">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>12</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Конфигурация</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_save_status">
|
||||||
|
<property name="text">
|
||||||
|
<string>Можно сохранить или загрузить</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="button_save">
|
||||||
|
<property name="text">
|
||||||
|
<string>Сохранить</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="button_load">
|
||||||
|
<property name="text">
|
||||||
|
<string>Загрузить</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer">
|
<spacer name="verticalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
@@ -353,6 +413,24 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_10">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_15">
|
||||||
|
<property name="text">
|
||||||
|
<string>Время измерения:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_meas_time">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3" stretch="1,1,2">
|
<layout class="QHBoxLayout" name="horizontalLayout_3" stretch="1,1,2">
|
||||||
<item>
|
<item>
|
||||||
@@ -374,6 +452,24 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_11">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_16">
|
||||||
|
<property name="text">
|
||||||
|
<string>Скважность:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_duty">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_4" stretch="1,1,2">
|
<layout class="QHBoxLayout" name="horizontalLayout_4" stretch="1,1,2">
|
||||||
<item>
|
<item>
|
||||||
@@ -395,6 +491,24 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_12">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_17">
|
||||||
|
<property name="text">
|
||||||
|
<string>Напряжение:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_voltage">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_5" stretch="1,1,2">
|
<layout class="QHBoxLayout" name="horizontalLayout_5" stretch="1,1,2">
|
||||||
<item>
|
<item>
|
||||||
@@ -423,6 +537,24 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_13">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_14">
|
||||||
|
<property name="text">
|
||||||
|
<string>Суммарное время:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_meas_total">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="button_start">
|
<widget class="QPushButton" name="button_start">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -453,6 +585,20 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QProgressBar" name="progress_measure">
|
||||||
|
<property name="value">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkbox_autorestart">
|
||||||
|
<property name="text">
|
||||||
|
<string>Авто-рестарт</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="checkbox_draw_reference">
|
<widget class="QCheckBox" name="checkbox_draw_reference">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
|||||||
Reference in New Issue
Block a user