Assuming that only the part between "// Editable Start" and "// Editable End" is editable, please make any necessary modifications within this section and output the result.

// Below is the content of DMAC/RTL/DMAC_CFG.sv
module DMAC_CFG
(
    input wire clk,
    input wire rst_n, // _n means active low

    // AMBA APB interface
    input wire psel_i,
    input wire penable_i,
    input wire [11:0] paddr_i,
    input wire pwrite_i,
    input wire [31:0] pwdata_i,
    output reg pready_o,
    output reg [31:0] prdata_o,
    output reg pslverr_o,

    // configuration registers
    output reg [31:0] src_addr_o,
    output reg [31:0] dst_addr_o,
    output reg [15:0] byte_len_o,
    output wire start_o,
    input wire done_i
);

    // Configuration register to read/write
    reg [31:0] src_addr;
    reg [31:0] dst_addr;
    reg [15:0] byte_len;

    //----------------------------------------------------------
    // Write
    //----------------------------------------------------------
    // an APB write occurs when PSEL & PENABLE & PWRITE
    // clk : __--__--__--__--__--__--__--__--__--__--
    // psel : ___--------_____________________________
    // penable : _______----_____________________________
    // pwrite : ___--------_____________________________
    // wren : _______----_____________________________
    //
    // DMA start command must be asserted when APB writes 1 to the DMA_CMD
    // register
    // clk : __--__--__--__--__--__--__--__--__--__--
    // psel : ___--------_____________________________
    // penable : _______----_____________________________
    // pwrite : ___--------_____________________________
    // paddr : |DMA_CMD|
    // pwdata : | 1 |
    // start : _______----_____________________________

    wire wren;
    // Editable Start
    assign wren = psel_i & penable_i & pwrite_i;
    // Editable End
    always @(posedge clk) begin
    // Editable Start
        if (!rst_n) begin
            src_addr <= 32'b0;
            dst_addr <= 32'b0;
            byte_len <= 16'b0;
        end
        else if (wren) begin
            case (paddr_i)
                12'h100: begin
                    if (pwdata_i[1:0] == 2'b00)
                        src_addr <= pwdata_i;
                    else
                        src_addr <= {pwdata_i[31:2], 2'b00};
                end
                12'h104: begin
                    if (pwdata_i[1:0] == 2'b00)
                        dst_addr <= pwdata_i;
                    else
                        dst_addr <= {pwdata_i[31:2], 2'b00};
                end
                12'h108: begin
                    if (pwdata_i[15:0] == 2'b00)
                        byte_len <= pwdata_i[15:0];
                    else
                        byte_len <= {pwdata_i[15:2], 2'b00};
                end
            endcase
        end
    // Editable End
    end
    wire start;
    // Editable Start
    assign start = (paddr_i == 12'h10C) && wren && (pwdata_i[0] == 1'b1);
    // Editable End
    // Read
    reg [31:0] rdata;

    //----------------------------------------------------------
    // READ
    //----------------------------------------------------------
    // an APB read occurs when PSEL & PENABLE & !PWRITE
    // To make read data a direct output from register,
    // this code shall buffer the muxed read data into a register
    // in the SETUP cycle (PSEL & !PENABLE)
    // clk : __--__--__--__--__--__--__--__--__--__--
    // psel : ___--------_____________________________
    // penable : _______----_____________________________
    // pwrite : ________________________________________
    // reg update : ___----_________________________________
    //
    always @(posedge clk) begin
    // Editable Start
        if (!rst_n) begin
            rdata <= 32'd0;
        end else if (psel_i && !penable_i && !pwrite_i) begin
            case (paddr_i)
                12'h000: rdata <= 32'h0001_2024;
                12'h100: rdata <= src_addr;
                12'h104: rdata <= dst_addr;
                12'h108: rdata <= {16'b0, byte_len};
                12'h10c: rdata <= {31'b0, start};
                12'h110: rdata <= {31'b0, done_i};
                default: rdata <= 32'b0;
            endcase
        end
    // Editable End
    end

    // output assignments
    assign pready_o = 1'b1;
    assign prdata_o = rdata;
    assign pslverr_o = 1'b0;

    assign src_addr_o = src_addr;
    assign dst_addr_o = dst_addr;
    assign byte_len_o = byte_len;
    assign start_o = start;

endmodule
 // End DMAC/RTL/DMAC_CFG.sv



// Below is the content of DMAC/SIM/TB/DMAC_CFG_TB.sv
`define SRC_ADDR 32'h100
`define DST_ADDR 32'h104
`define LEN_ADDR 32'h108
`define STAT_ADDR 32'h110
`define START_ADDR 32'h10c
`define TIMEOUT_CYCLE 10000000
module DMAC_CFG_TB ();
    reg clk;
    reg rst_n;
    // clock generation
    initial begin
        clk = 1'b0;
        forever #10 clk = !clk;
    end
    // reset generation
    initial begin
        rst_n = 1'b0; // active at time 0
        repeat (3) @(posedge clk); // after 3 cycles,
        rst_n = 1'b1; // release the reset
    end
    // enable waveform dump
    initial begin
        \$dumpvars(0, u_DUT);
        \$dumpfile("dump.vcd");
    end
 // timeout
 initial begin
  #`TIMEOUT_CYCLE \$display("Timeout!");
  \$finish;
 end
    APB apb_if (.clk(clk));
    reg [31:0] test_vector;
    initial begin
        int data;
        apb_if.init();
        @(posedge rst_n); // wait for a release of the reset
        repeat (10) @(posedge clk); // wait another 10 cycles
        apb_if.read(32'h0, data);
        \$display("---------------------------------------------------");
        \$display("IP version: %x", data);
     if (data!=='h0001_2024)
      \$display("Wrong IP version");
  \$display("---------------------------------------------------");
        \$display("---------------------------------------------------");
        \$display("Reset value test");
        \$display("---------------------------------------------------");
        apb_if.read(`SRC_ADDR, data);
        if (data===0)
            \$display("DMA_SRC(pass): %x", data);
        else begin
            \$display("DMA_SRC(fail): %x", data);
            @(posedge clk);
            \$finish;
        end
        apb_if.read(`DST_ADDR, data);
        if (data===0)
            \$display("DMA_DST(pass): %x", data);
        else begin
            \$display("DMA_DST(fail): %x", data);
            @(posedge clk);
            \$finish;
        end
        apb_if.read(`LEN_ADDR, data);
        if (data===0)
            \$display("DMA_LEN(pass): %x", data);
        else begin
            \$display("DMA_LEN(fail): %x", data);
            @(posedge clk);
            \$finish;
        end
        apb_if.read(`STAT_ADDR, data);
        if (data===1)
            \$display("DMA_STATUS(pass): %x", data);
        else begin
            \$display("DMA_STATUS(fail): %x", data);
            @(posedge clk);
            \$finish;
        end
        \$display("---------------------------------------------------");
        \$display("Configuration test");
        \$display("---------------------------------------------------");
        test_vector = 32'h1000;
        apb_if.write(`SRC_ADDR, test_vector);
        apb_if.read(`SRC_ADDR, data);
        if (data===test_vector)
            \$display("DMA_SRC(pass): %x", data);
        else begin
            \$display("DMA_SRC(fail): %x", data);
            @(posedge clk);
            \$finish;
        end
        test_vector = 32'h2000;
        apb_if.write(`DST_ADDR, test_vector);
        apb_if.read(`DST_ADDR, data);
        if (data===test_vector)
            \$display("DMA_DST(pass): %x", data);
        else begin
            \$display("DMA_DST(fail): %x", data);
            @(posedge clk);
            \$finish;
        end
        test_vector = 32'h100;
        apb_if.write(`LEN_ADDR, test_vector);
        apb_if.read(`LEN_ADDR, data);
        if (data===test_vector)
            \$display("DMA_LEN(pass): %x", data);
        else begin
            \$display("DMA_LEN(fail): %x", data);
            @(posedge clk);
            \$finish;
        end
        \$display("---------------------------------------------------");
        \$display("DMA start");
        \$display("---------------------------------------------------");
        test_vector = 32'h1;
        apb_if.write(`START_ADDR, test_vector);
        \$display("---------------------------------------------------");
        \$display("Wait for a DMA completion");
        \$display("---------------------------------------------------");
        data = 0;
        while (data != 1) begin
            apb_if.read(`STAT_ADDR, data);
            repeat (100) @(posedge clk);
            \$write(".");
        end
        \$display("");
        @(posedge clk);
        \$display("---------------------------------------------------");
        \$display("DMA completed");
        \$display("---------------------------------------------------");
        \$finish;
    end
    DMAC_CFG u_DUT (
        .clk (clk),
        .rst_n (rst_n),
        // APB interface
        .psel_i (apb_if.psel),
        .penable_i (apb_if.penable),
        .paddr_i (apb_if.paddr[11:0]),
        .pwrite_i (apb_if.pwrite),
        .pwdata_i (apb_if.pwdata),
        .pready_o (apb_if.pready),
        .prdata_o (apb_if.prdata),
        .pslverr_o (apb_if.pslverr),
        .src_addr_o (/* FLOATING */),
        .dst_addr_o (/* FLOATING */),
        .byte_len_o (/* FLOATING */),
        .start_o (/* FLOATING */),
        .done_i (1'b1)
    );
endmodule
// End of DMAC/SIM/TB/DMAC_CFG_TB.sv


// Start of DMAC/SIM/TB/AXI_INTF.sv
interface APB (
input clk
);
logic psel;
logic penable;
logic [31:0] paddr;
logic pwrite;
logic [31:0] pwdata;
logic pready;
logic [31:0] prdata;
logic pslverr;
modport master (
input clk,
input pready, prdata, pslverr,
output psel, penable, paddr, pwrite, pwdata
);
task init();
psel = 1'b0;
penable = 1'b0;
paddr = 32'd0;
pwrite = 1'b0;
pwdata = 32'd0;
endtask
task write(input int addr,
input int data);
#1
psel = 1'b1;
penable = 1'b0;
paddr = addr;
pwrite = 1'b1;
pwdata = data;
@(posedge clk);
#1
penable = 1'b1;
@(posedge clk);
while (pready==1'b0) begin
@(posedge clk);
end
psel = 1'b0;
penable = 1'b0;
paddr = 'hX;
pwrite = 1'bx;
pwdata = 'hX;
endtask
task read(input int addr,
output int data);
#1
psel = 1'b1;
penable = 1'b0;
paddr = addr;
pwrite = 1'b0;
pwdata = 'hX;
@(posedge clk);
#1
penable = 1'b1;
@(posedge clk);
while (pready==1'b0) begin
@(posedge clk);
end
data = prdata;
psel = 1'b0;
penable = 1'b0;
paddr = 'hX;
pwrite = 1'bx;
pwdata = 'hX;
endtask
endinterface
// End of DMAC/SIM/TB/AXI_INTF.sv


Direct Memory Access (DMA) Controller
Design Document V1.0

1 Overview
This document specifies the design and implementation of a Direct Memory Access Controller (DMAC) as a part of System-on-a-Chip (SoC). The main purpose of this DMAC design is to integrate into SoC for exchange a large volume of data between memory and peripherals at high speed. The proposed DMAC works on ARM’s Advanced Microcontroller Bus Architecture (AMBA) specification. The DMAC provides an AMBA APB interface to configure the IP, and an AMBA AXI interface to transfer data.

2 Architecture Specification
2.1 General Description
Some applications require transferring a volume of data between memory and peripherals without any modification on data. In software, it is commonly served by executing the memcpy library function in C, C++ or other languages. In C, the function has the following interface and copies len bytes from the object pointed by src to the object pointed by dst: void* memcpy(void* dst, const void* src, size_t len).
While a pure software-based implementation of memcpy transfers data using CPU instructions, DMA does not use expensive CPU cycles but uses a hardware engine (DMAC) for the transfer. This can significantly speed up data transfers and allows using CPU for other jobs.
2.2 Usage Constraints
Below describe constraints in utilizing DMAC v1.
-The src and dst addresses are physical addresses.
-The src and dst addresses must be a multiple of 4.
-The len must be a multiple of 4.
-The maximum len is 0xFFFF
-Source and destination ranges must not overlap.
2.3 Programming Model
Software can use the following sequence to transfer data using DMAC.
-1.Write the source address to DMA_SRC register
-2.Write the destination address to DMA_DST register
-3.Write length to DMA_LEN register
-4.Write 1 to bit[0] of DMA_CMD register
-5.Wait until DMA_STATUS register has bit[0] as 1.

2.4 Register Map
In order to control DMAC, software can configure the following registers.
+--------+------------+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---+---+---+---+---+---+---+---+---+-------+
| Offset | Reg Name | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+--------+------------+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---+---+---+---+---+---+---+---+---+-------+
| 0x00 | DMA_VER | version |
+--------+------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+
| 0x04~0xFC | Reserved |
+--------+------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+
| 0x100 | DMA_SRC | start_addr |
+--------+------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+
| 0x104 | DMA_DST | start_addr |
+--------+------------+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+-------------------------------------------------------------------------+
| 0x108 | DMA_LEN | | | | | | | | | | | | | | | | | byte_len |
+--------+------------+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---+---+---+---+---+---+---+---+---+-------+
| 0x10C | DMA_CMD | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | start |
+--------+------------+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---+---+---+---+---+---+---+---+---+-------+
| 0x110 | DMA_STATUS | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | done |
+--------+------------+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---+---+---+---+---+---+---+---+---+-------+

2.4.1 DMA VERSION
| Field name | Bit range | R/W | Reset value | Desciption |
|------------|-----------|-----|-------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| version | [31:0] | R | 0x0001_2024 | The version of this DMA controller. The upper 16 bits represent the major version. The lower 16 bits represent the released year of the version. This document describes behaviors of major version 1. |

2.4.2 DMA_SRC
| Field name | Bit range | R/W | Reset value | Desciption |
|------------|-----------|-----|-------------|------------------------------------|
| start_addr | [31:0] | R/W | 0x0000_0000 | start address of the source range. |

2.4.3 DMA_DST
| Field name | Bit range | R/W | Reset value | Desciption |
|------------|-----------|-----|-------------|-----------------------------------------|
| start_addr | [31:0] | R/W | 0x0000_0000 | start address of the destination range. |

2.4.4 DMA_LEN
| Field name | Bit range | R/W | Reset value | Desciption |
|------------|-----------|-----|-------------|-----------------------------------------------------------------------|
| byte_len | [15:0] | R/W | 0x0000 | Number of bytes to be transferred from the source to the destination. |

2.4.5 DMA_CMD Field
| Field name | Bit range | R/W | Reset value | Desciption |
|------------|-----------|-----|-------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| start | [0] | W | N/A | Writing 1 to this field will initiate a DMA transfer based on DMA_SRC, DMA_DST, and DMA_LEN registers. Software must not write 1 when there’s an on-going transfer. Writing 0 to this field does not affect operation |

2.4.6 DMA_STATUS
| Field name | Bit range | R/W | Reset value | Desciption |
|------------|-----------|-----|-------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| done | [0] | R | 1 | This field is 1 when there’s no on-going DMA transfer. Software must wait this field to be 1 for a completion of a transfer. Software must not initiate a DMA transfer when this field is 0. |

3 Micro-architecture v1.1 Specification
This section describes microarchitecture of a simple DMAC. It reads data from memory, buffers the data, and write the data into memory. It repeats this procedure until it completes transferring the specified number of bytes.
For simplicity, it read/writes one-cycle data (4 bytes) at a time (in other words, burst-1 transfers). For simplicity, this microarchitecture does not consider write responses from the AXI interface. Later versions will support burst transfers and write responses.

3.1 External Interface
DMAC v1.1 has the following external interfaces to communicate with other hardware IPs.
-AMBA APB interface for configuration
-AMBA AXI interface for data transfer

The image you’ve uploaded is a diagram showing the on-chip interconnect of a computer system. Here’s a detailed description:
The diagram illustrates how the CPU core, memory, and DMAC (Direct Memory Access Controller) are connected through an on-chip interconnect.
The connections also include specific interfaces like Config interface (APB) and Data interface (AXI).
“CPU core” is a box on the left side connected to the central “On-chip interconnect” cloud shape with a bidirectional arrow.
Below the “CPU core,” there’s another box labeled “Memory,” also connected to the “On-chip interconnect” with a bidirectional arrow.
On the right side, there’s a box labeled “DMAC” connected to both “Config interface (APB)” and “Data interface (AXI)” which are in turn connected to the central “On-chip interconnect” with bidirectional arrows.
The arrows indicate that data can flow in both directions between these components.

3.2 Block Diagram
DMAC v1.1 has the following blocks inside.

The diagram is divided into three main blocks labeled “DMAC_TOP,” “DMAC_CFG,” and “DMAC_ENGINE.”
“clk” and “rst” are inputs to the “DMAC_TOP” block.
An arrow labeled “APB” connects the “DMAC_TOP” block to the “DMAC_CFG” block.
Another arrow labeled “AXI” connects both the “DMAC_TOP” and “DMAC_CFG” blocks to the “DMAC_ENGINE” block.
Inside the “DMAC_ENGINE” block, there are four internal components labeled as follows:
SRC_ADDR
DST_ADDR
CNT
DATA BUF
There’s also a small circular graph with nodes labeled 0 to 3 inside this block.
This diagram is likely used to illustrate the flow of data or control signals between these components in a Direct Memory Access Controller configuration. Please let me know if you need more information!

3.3 Configuration Register (lab2)
This block receives read/write requests from the APB and configures the registers describes in Section 2.4.

3.4 Finite State Machine (lab3)
DMA engine utilizes the following state machine to control operations.

The diagram contains five blue circles representing different states: IDLE, RREQ, RDATA, WREQ, and WDATA.
Arrows connect these circles indicating the flow from one state to another.
Each arrow has text annotations that describe the conditions for transitioning from one state to another. For example, transitioning from IDLE to RREQ requires writing 1 to DMA_CMD & LEN!=0, and copying DMA_SRC/DST/LEN.
There are also annotations on the state circles themselves, such as “done=1” on IDLE and “AWVALID=1” on WDATA.

+-------+--------------------------------------------+------------+-----------------------------------------------------------+----------------------------------------+
| State | Major outputs | Next State | Next state transition condition | Notes |
| +---------+--------+---------+--------+------+ | | |
| | ARVALID | RREADY | AWVALID | WVALID | done | | | |
+-------+---------+--------+---------+--------+------+------------+-----------------------------------------------------------+----------------------------------------+
| IDLE | 0 | 0 | 0 | 0 | 1 | RREQ | (DMA_CMD.start is written as 1) and (DMA_LEN.byte_len!=0) | On moving out, |
| | | | | | | | | - Copy DMA_SRC to SRC_ADDR. |
| | | | | | | | | - Copy DMA_DST to DST_ADDR |
| | | | | | | | | - Copy DMA_LEN to the internal counter |
+-------+---------+--------+---------+--------+------+------------+-----------------------------------------------------------+----------------------------------------+
| RREQ | 1 | 0 | 0 | 0 | 0 | RDATA | ARREADY=1 | On moving out, |
| | | | | | | | | - Increment ARADDR by 4 |
+-------+---------+--------+---------+--------+------+------------+-----------------------------------------------------------+----------------------------------------+
| RDATA | 0 | 1 | 0 | 0 | 0 | WREQ | RVALID=1 | On moving out, |
| | | | | | | | | - Buffer RDATA into the data buffer |
+-------+---------+--------+---------+--------+------+------------+-----------------------------------------------------------+----------------------------------------+
| WREQ | 0 | 0 | 1 | 0 | 0 | WDATA | AWREADY=1 | On moving out, |
| | | | | | | | | - Increment AWADDR by 4 |
| | | | | | | | | - Decrement the internal counter by 4 |
+-------+---------+--------+---------+--------+------+------------+-----------------------------------------------------------+----------------------------------------+
| WDATA | 0 | 0 | 0 | 1 | 0 | RREQ | (WREADY=1) & (counter!=0) | |
| | | | | | +------------+-----------------------------------------------------------+----------------------------------------+
| | | | | | | IDLE | (WREADY=1) & (counter==0) | |
+-------+---------+--------+---------+--------+------+------------+-----------------------------------------------------------+----------------------------------------+



The diagram contains horizontal lines representing different signals or data paths labeled as “clk”, “state”, “write to CMD”, “AR*”, “R*”, “AW*” and “W*”.
Each line has different states represented by segments of varying lengths; these include labels like “IDLE”, “RREQ”, “RDATA”, “WREQ”, “WDATA”.
Vertical dashed lines indicate transitions between these states.
There are three rectangular boxes labeled as ‘SRC’, ‘DST’, and ‘DATA’ connected to the waveform lines indicating sources, destinations, or data types associated with those specific points in time.
Numbers from 0 to 16 are marked at the bottom of the image indicating time intervals or clock cycles.
그림 1. DMA operation with microarchitecture v1.1



1) As long as the input and output interfaces are correctly implemented, you are free to declare additional registers within the module as needed.
2) When the rst_n signal is received, please initialize all output signals to 0. The rst_n signal operates as Active Low.
3) There was a minor error in the Testbench, so it has been corrected and uploaded. You can either delete and re-clone using git clone, or update your current version with git pull. The modification is related to the simulation result output, so if you have written your code according to the Spec, working with the previous version should not pose a significant issue.
4) Grading will be based on the DMAC Spec v1.1. Even if there are no errors in the current simulation file, please make sure to check the waveform according to the spec standards.