transferring test for controller dma ram connective
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
// 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
|
||||
@@ -0,0 +1,60 @@
|
||||
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
|
||||
@@ -0,0 +1,193 @@
|
||||
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
|
||||
@@ -0,0 +1,48 @@
|
||||
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
|
||||
@@ -0,0 +1,298 @@
|
||||
|
||||
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
|
||||
@@ -0,0 +1,194 @@
|
||||
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
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
# 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]
|
||||
Reference in New Issue
Block a user