mirror of
https://github.com/aolofsson/oh.git
synced 2025-02-07 06:44:09 +08:00
Implemented DMA state machine
- Work in progress
This commit is contained in:
parent
26515bc1e9
commit
9bec938914
@ -4,34 +4,185 @@
|
|||||||
//# Author: Andreas Olofsson #
|
//# Author: Andreas Olofsson #
|
||||||
//# License: MIT (see below) #
|
//# License: MIT (see below) #
|
||||||
//#############################################################################
|
//#############################################################################
|
||||||
|
|
||||||
|
`include "edma_regmap.vh"
|
||||||
module edma_ctrl (/*AUTOARG*/
|
module edma_ctrl (/*AUTOARG*/
|
||||||
// Outputs
|
// Outputs
|
||||||
dma_state, outerloop, master_active, update,
|
fetch_access, fetch_packet, dma_state, update, update2d,
|
||||||
|
master_active,
|
||||||
// Inputs
|
// Inputs
|
||||||
clk, nreset, dma_en, chainmode, mastermode, access_in, wait_in
|
clk, nreset, dma_en, chainmode, manualmode, mastermode, count,
|
||||||
|
curr_descr, next_descr, reg_wait_in, access_in, wait_in
|
||||||
);
|
);
|
||||||
|
|
||||||
// clk, reset, config
|
parameter AW = 32; // address width
|
||||||
input clk; // main clock
|
localparam PW = 2*AW+40; // fetch packet width
|
||||||
input nreset; // async active low reset
|
parameter ID = 4'b0000; // group id for DMA regs [10:8]
|
||||||
input dma_en; // dma is enabled
|
|
||||||
input chainmode; // chainmode configuration
|
|
||||||
input mastermode; // dma configured in mastermode
|
|
||||||
|
|
||||||
// packet control
|
|
||||||
input access_in; // slave access
|
|
||||||
input wait_in; // controls machine stall
|
|
||||||
|
|
||||||
// status
|
|
||||||
output [2:0] dma_state; // state of dma
|
|
||||||
output outerloop; // dma currently in outerloop (2D)
|
|
||||||
output master_active;// master is active
|
|
||||||
output update; // update registers
|
|
||||||
|
|
||||||
assign update = ~wait_in &
|
|
||||||
(master_active | access_in);
|
|
||||||
|
|
||||||
|
// clk, reset, config
|
||||||
|
input clk; // main clock
|
||||||
|
input nreset; // async active low reset
|
||||||
|
input dma_en; // dma is enabled
|
||||||
|
input chainmode; // chainmode configuration
|
||||||
|
input manualmode; // descriptor fetch
|
||||||
|
input mastermode; // dma configured in mastermode
|
||||||
|
input [31:0] count; // current transfer count
|
||||||
|
input [15:0] curr_descr;
|
||||||
|
input [15:0] next_descr;
|
||||||
|
|
||||||
|
// descriptor fetch interface
|
||||||
|
output fetch_access; // fetch descriptor
|
||||||
|
output [PW-1:0] fetch_packet; // fetch packet
|
||||||
|
input reg_wait_in; // register access wait
|
||||||
|
|
||||||
|
// slave access
|
||||||
|
input access_in; // slave access
|
||||||
|
input wait_in; // master/slave transfer stall
|
||||||
|
|
||||||
|
// status
|
||||||
|
output [3:0] dma_state; // state of dma
|
||||||
|
output update; // update registers
|
||||||
|
output update2d; // dma currently in outerloop (2D)
|
||||||
|
output master_active; // master is active
|
||||||
|
|
||||||
|
//###########################################################################
|
||||||
|
//# BODY
|
||||||
|
//###########################################################################
|
||||||
|
|
||||||
|
reg [3:0] dma_state;
|
||||||
|
wire [15:0] descr;
|
||||||
|
wire [15:0] fetch_addr;
|
||||||
|
wire [AW-1:0] srcaddr_out;
|
||||||
|
wire [4:0] reg_addr;
|
||||||
|
|
||||||
|
//###########################################
|
||||||
|
//# STATE MACHINE
|
||||||
|
//###########################################
|
||||||
|
|
||||||
|
`define DMA_IDLE 4'b0000 // dma idle
|
||||||
|
`define DMA_FETCH0 4'b0001 // fetch cfg, next-ptr, stride_in
|
||||||
|
`define DMA_FETCH1 4'b0010 // fetch cnt_out,cnt_in, stride_out
|
||||||
|
`define DMA_FETCH2 4'b0011 // fetch srcaddr, dstaddr
|
||||||
|
`define DMA_FETCH3 4'b0100 // fetch srcaddr64, dstaddr64
|
||||||
|
`define DMA_FETCH4 4'b0101 // stall (no bypass)
|
||||||
|
`define DMA_INNER 4'b0110 // dma inner loop
|
||||||
|
`define DMA_OUTER 4'b0111 // dma outer loop
|
||||||
|
`define DMA_DONE 4'b1000 // dma outer loop
|
||||||
|
`define DMA_ERROR 4'b1001 // dma error
|
||||||
|
|
||||||
|
always @ (posedge clk or negedge nreset)
|
||||||
|
if(!nreset)
|
||||||
|
dma_state[3:0] <= `DMA_IDLE;
|
||||||
|
else if(dma_error)
|
||||||
|
dma_state[3:0] <= `DMA_ERROR;
|
||||||
|
else
|
||||||
|
case(dma_state[3:0])
|
||||||
|
`DMA_IDLE:
|
||||||
|
casez({dma_en,manualmode})
|
||||||
|
2'b0? : dma_state[3:0] <= `DMA_IDLE;
|
||||||
|
2'b11 : dma_state[3:0] <= `DMA_INNER;
|
||||||
|
2'b10 : dma_state[3:0] <= `DMA_FETCH0;
|
||||||
|
endcase // casez (dma_reg_write_config)
|
||||||
|
`DMA_FETCH0:
|
||||||
|
dma_state[3:0] <= reg_wait_in ? `DMA_FETCH0 : `DMA_FETCH1;
|
||||||
|
`DMA_FETCH1:
|
||||||
|
dma_state[3:0] <= reg_wait_in ? `DMA_FETCH1 : `DMA_FETCH2;
|
||||||
|
`DMA_FETCH2:
|
||||||
|
dma_state[3:0] <= reg_wait_in ? `DMA_FETCH2 : `DMA_FETCH3;
|
||||||
|
`DMA_FETCH3:
|
||||||
|
dma_state[3:0] <= reg_wait_in ? `DMA_FETCH3 : `DMA_FETCH3;
|
||||||
|
`DMA_FETCH4:
|
||||||
|
dma_state[3:0] <= reg_wait_in ? `DMA_FETCH4 : `DMA_INNER;
|
||||||
|
`DMA_INNER:
|
||||||
|
casez({update,incount_zero,outcount_zero})
|
||||||
|
3'b0?? : dma_state[3:0] <= `DMA_INNER;
|
||||||
|
3'b10? : dma_state[3:0] <= `DMA_INNER;
|
||||||
|
3'b110 : dma_state[3:0] <= `DMA_OUTER;
|
||||||
|
3'b111 : dma_state[3:0] <= `DMA_DONE;
|
||||||
|
endcase
|
||||||
|
`DMA_OUTER:
|
||||||
|
dma_state[3:0] <= update ? `DMA_INNER : `DMA_OUTER;
|
||||||
|
`DMA_DONE:
|
||||||
|
casez({chainmode,manualmode})
|
||||||
|
2'b0? : dma_state[3:0] <= `DMA_DONE;
|
||||||
|
2'b11 : dma_state[3:0] <= `DMA_IDLE;
|
||||||
|
2'b10 : dma_state[3:0] <= `DMA_FETCH0;
|
||||||
|
endcase
|
||||||
|
`DMA_ERROR:
|
||||||
|
dma_state[3:0] <= dma_en ? `DMA_ERROR: `DMA_IDLE;
|
||||||
|
endcase
|
||||||
|
|
||||||
|
//###########################################
|
||||||
|
//# ACTIVE SIGNALS
|
||||||
|
//###########################################
|
||||||
|
|
||||||
|
assign dma_error = 1'b0; //TODO: define error conditions
|
||||||
|
|
||||||
|
assign update = ~wait_in & (master_active | access_in);
|
||||||
|
|
||||||
|
assign update2d = update & (dma_state[3:0]==`DMA_OUTER);
|
||||||
|
|
||||||
|
assign master_active = mastermode &
|
||||||
|
((dma_state[3:0]==`DMA_INNER) |
|
||||||
|
(dma_state[3:0]==`DMA_OUTER));
|
||||||
|
|
||||||
|
|
||||||
|
assign incount_zero = ~(|count[15:0]);
|
||||||
|
|
||||||
|
assign outcount_zero = ~(|count[31:16]);
|
||||||
|
|
||||||
|
//###########################################
|
||||||
|
//# DESCRIPTOR FETCH ENGINE
|
||||||
|
//###########################################
|
||||||
|
|
||||||
|
assign fetch_access = (dma_state[3:0]==`DMA_FETCH0) |
|
||||||
|
(dma_state[3:0]==`DMA_FETCH1) |
|
||||||
|
(dma_state[3:0]==`DMA_FETCH2);
|
||||||
|
|
||||||
|
|
||||||
|
// fetch address
|
||||||
|
assign descr[15:0] = (dma_state[3:0]==`DMA_FETCH0) ? next_descr[15:0] :
|
||||||
|
curr_descr[15:0];
|
||||||
|
|
||||||
|
oh_mux3 #(.DW(16))
|
||||||
|
mux3d (.out (fetch_addr[15:0]),
|
||||||
|
.in0 (descr[15:0]), .sel0 (dma_state[3:0]==`DMA_FETCH0),
|
||||||
|
.in1 (descr[15:0]+16'd8), .sel1 (dma_state[3:0]==`DMA_FETCH1),
|
||||||
|
.in2 (descr[15:0]+16'd16), .sel2 (dma_state[3:0]==`DMA_FETCH2)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//address of first reg to fetch
|
||||||
|
oh_mux3 #(.DW(5))
|
||||||
|
mux3s (.out (reg_addr[4:0]),
|
||||||
|
.in0 (`EDMA_CONFIG), .sel0 (dma_state[3:0]==`DMA_FETCH0),
|
||||||
|
.in1 (`EDMA_COUNT), .sel1 (dma_state[3:0]==`DMA_FETCH1),
|
||||||
|
.in2 (`EDMA_SRCADDR), .sel2 (dma_state[3:0]==`DMA_FETCH2)
|
||||||
|
);
|
||||||
|
|
||||||
|
// constructing the address to return fetch to
|
||||||
|
assign srcaddr_out[AW-1:0] = {{(AW-11){1'b0}}, //31-11
|
||||||
|
ID, //10-7
|
||||||
|
reg_addr[4:0], //6-2
|
||||||
|
2'b0}; //1-0
|
||||||
|
|
||||||
|
// constructing fetch packet
|
||||||
|
emesh2packet #(.AW(AW))
|
||||||
|
e2p (//outputs
|
||||||
|
.packet_out (fetch_packet[PW-1:0]),
|
||||||
|
//inputs
|
||||||
|
.write_out (1'b0),
|
||||||
|
.datamode_out (2'b11),
|
||||||
|
.ctrlmode_out (5'b0),
|
||||||
|
.dstaddr_out ({{(AW-16){1'b0}},fetch_addr[15:0]}),
|
||||||
|
.data_out ({(AW){1'b0}}),
|
||||||
|
.srcaddr_out (srcaddr_out[AW-1:0]));
|
||||||
|
|
||||||
|
|
||||||
endmodule // edma_ctrl
|
endmodule // edma_ctrl
|
||||||
|
// Local Variables:
|
||||||
|
// verilog-library-directories:("." "../hdl" "../../common/hdl" "../../emesh/hdl")
|
||||||
|
// End:
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// The MIT License (MIT) //
|
// The MIT License (MIT) //
|
||||||
|
Loading…
x
Reference in New Issue
Block a user