#Slave
- DMAC의 slave interface에 들어오는 signal에 대하여 처리하는 DMAC 내부 component
- Register I/O 및 Interrupt를 제어하는 component
module dmac_slave(
clk,
reset_n,
//Slave interface
S_sel,
S_address,
S_wr,
S_din,
S_dout,
//Interrupt signal
interrupt,
//Inner interface
dmac_opstart,
dmac_opdone,
dmac_opdone_clear,
dmac_state,
fifo_wren,
fifo_din0_srcaddr,
fifo_din1_destaddr,
fifo_din2_datasize,
fifo_data_count
);
input clk;
input reset_n;
//Slave interface
input S_sel;
input [7:0] S_address;
input S_wr;
input [7:0] S_din;
output [7:0] S_dout;
//Interrupt signal
output interrupt;
//Inner interface
output dmac_opstart;
input dmac_opdone;
output dmac_opdone_clear;
input [2:0] dmac_state;
output fifo_wren;
output [7:0] fifo_din0_srcaddr;
output [7:0] fifo_din1_destaddr;
output [7:0] fifo_din2_datasize;
input [3:0] fifo_data_count;
/////////////////////////////////////////////////////////
//offset = 0x0's [0] bits
/////////////////////////////////////////////////////////
reg r_OPSTART, next_OPSTART;
//about next_OPSTART
always@(S_sel, S_address, S_wr, S_din, dmac_state, dmac_opdone )
begin
if((S_sel==1)
&& (S_wr==1)
&& (S_address[3:0]==4'h0)
&& (S_din[0]==1'b1)
&& (dmac_state==3'b000)
&& (dmac_opdone==1'b0))
next_OPSTART = 1'b1;
else next_OPSTART = 1'b0;
end
//about r_OPSTART register(r_OPERATION[0] register)
always@(posedge clk or negedge reset_n)
begin
if(reset_n==0) r_OPSTART = 1'b0;
else if(reset_n==1) r_OPSTART = next_OPSTART;
else r_OPSTART = 1'bx;
end
assign dmac_opstart = r_OPSTART;
/////////////////////////////////////////////////////////
//offset = 0x1's [0] bits
/////////////////////////////////////////////////////////
reg r_OPERATION_DONE_CLEAR, next_OPERATION_DONE_CLEAR;
//about r_OPERATION_DONE_CLEAR register
always@(posedge clk or negedge reset_n)
begin
if(reset_n==0) r_OPERATION_DONE_CLEAR = 1'b0;
else if(reset_n==1) r_OPERATION_DONE_CLEAR = next_OPERATION_DONE_CLEAR;
else r_OPERATION_DONE_CLEAR = 1'bx;
end
//about next_OPERATION_DONE_CLEAR
always@(S_sel, S_address, S_wr, S_din, dmac_opdone)
begin
if((S_sel==1)
&& (S_wr==1)
&& (S_address[3:0]==4'h1)
&& (S_din[0] == 1'b1)
&& (dmac_opdone == 1'b1))
next_OPERATION_DONE_CLEAR = 1'b1;
else next_OPERATION_DONE_CLEAR = 1'b0;
end
assign dmac_opdone_clear = r_OPERATION_DONE_CLEAR;
/////////////////////////////////////////////////////////
//offset = 0x2's [0] bits
/////////////////////////////////////////////////////////
reg r_INTERRUPT_ENABLE, next_INTERRUPT_ENABLE;
//about next_INTERRUPT_ENABLE
always@(S_sel, S_address, S_wr, S_din, r_INTERRUPT_ENABLE)
begin
if((S_sel==1)
&& (S_wr==1)
&& (S_address[3:0]==4'h2))
next_INTERRUPT_ENABLE = S_din[0];
else next_INTERRUPT_ENABLE = r_INTERRUPT_ENABLE;
end
//about r_INTERRUPT_ENABLE register
always@(posedge clk or negedge reset_n)
begin
if(reset_n==0) r_INTERRUPT_ENABLE = 1'b0;
else if(reset_n==1) r_INTERRUPT_ENABLE = next_INTERRUPT_ENABLE;
else r_INTERRUPT_ENABLE = 1'bx;
end
/////////////////////////////////////////////////////////
//Interrupt
/////////////////////////////////////////////////////////
assign interrupt = (r_INTERRUPT_ENABLE==1'b1)?dmac_opdone:1'b0;
/////////////////////////////////////////////////////////
//offset = 0x3's [0] bits
/////////////////////////////////////////////////////////
reg r_FIFO_WREN, next_FIFO_WREN;
//about next_FIFO_WREN
always@(S_sel, S_address, S_wr, S_din)
begin
if((S_sel==1)
&& (S_wr==1)
&& (S_address[3:0]==4'h3)
&& (S_din[0] == 1'b1))
next_FIFO_WREN = 1'b1;
else next_FIFO_WREN = 1'b0;
end
//about r_FIFO_WREN
always@(posedge clk or negedge reset_n)
begin
if(reset_n==0) r_FIFO_WREN = 1'b0;
else if(reset_n==1) r_FIFO_WREN = next_FIFO_WREN;
else r_FIFO_WREN = 1'bx;
end
assign fifo_wren = r_FIFO_WREN;
/////////////////////////////////////////////////////////
//offset = 0x4
/////////////////////////////////////////////////////////
reg [7:0] r_SOURCE_ADDRESS, next_SOURCE_ADDRESS;
//about next_SOURCE_ADDRESS
always@(S_sel, S_address, S_wr, S_din, r_SOURCE_ADDRESS)
begin
if(S_sel &&(S_address[3:0]==4'h4) && S_wr) next_SOURCE_ADDRESS = S_din;
else next_SOURCE_ADDRESS = r_SOURCE_ADDRESS;
end
//about r_SOURCE_ADDRESS register
always@(posedge clk or negedge reset_n)
begin
if(reset_n==0) r_SOURCE_ADDRESS = 8'h00;
else if(reset_n==1) r_SOURCE_ADDRESS = next_SOURCE_ADDRESS;
else r_SOURCE_ADDRESS = 8'hxx;
end
assign fifo_din0_srcaddr = r_SOURCE_ADDRESS;
/////////////////////////////////////////////////////////
//offset = 0x5
/////////////////////////////////////////////////////////
reg [7:0] r_DESTINATION_ADDRESS, next_DESTINATION_ADDRESS;
//about next_DESTINATION_ADDRESS
always@(S_sel, S_address, S_wr, S_din, r_DESTINATION_ADDRESS)
begin
if(S_sel &&(S_address[3:0]==4'h5) && S_wr) next_DESTINATION_ADDRESS = S_din;
else next_DESTINATION_ADDRESS = r_DESTINATION_ADDRESS;
end
//about r_DESTINATION_ADDRESS register
always@(posedge clk or negedge reset_n)
begin
if(reset_n==0) r_DESTINATION_ADDRESS = 8'h00;
else if(reset_n==1) r_DESTINATION_ADDRESS = next_DESTINATION_ADDRESS;
else r_DESTINATION_ADDRESS = 8'hxx;
end
assign fifo_din1_destaddr = r_DESTINATION_ADDRESS;
/////////////////////////////////////////////////////////
//offset = 0x6
/////////////////////////////////////////////////////////
reg [7:0] r_DATA_SIZE, next_DATA_SIZE;
//about next_DATA_SIZE
always@(S_sel, S_address, S_wr, S_din, r_DATA_SIZE)
begin
if(S_sel &&(S_address[3:0]==4'h6) && S_wr) next_DATA_SIZE = S_din;
else next_DATA_SIZE = r_DATA_SIZE;
end
//about r_DATA_SIZE register
always@(posedge clk or negedge reset_n)
begin
if(reset_n==0) r_DATA_SIZE = 8'h00;
else if(reset_n==1) r_DATA_SIZE = next_DATA_SIZE;
else r_DATA_SIZE = 8'hxx;
end
assign fifo_din2_datasize = r_DATA_SIZE;
/////////////////////////////////////////////////////////
//Slave dataout
/////////////////////////////////////////////////////////
reg [7:0] S_dout, next_S_dout;
//about register S_dout
always@(posedge clk or negedge reset_n)
begin
if(reset_n==0) S_dout = 8'h00;
else if(reset_n==1) S_dout = next_S_dout;
else S_dout = 8'hxx;
end
//about next_S_dout
always@(S_sel, S_address, S_wr, dmac_opdone, r_INTERRUPT_ENABLE, r_SOURCE_ADDRESS, r_DESTINATION_ADDRESS, r_DATA_SIZE, fifo_data_count)
begin
if((S_sel == 1'b1) && (S_wr == 1'b0))
begin
if(S_address[3:0]==4'h1) next_S_dout = {7'b0000000, dmac_opdone};
else if(S_address[3:0]==4'h2) next_S_dout = {7'b0000000, r_INTERRUPT_ENABLE};
else if(S_address[3:0]==4'h4) next_S_dout = r_SOURCE_ADDRESS;
else if(S_address[3:0]==4'h5) next_S_dout = r_DESTINATION_ADDRESS;
else if(S_address[3:0]==4'h6) next_S_dout = r_DATA_SIZE;
else if(S_address[3:0]==4'h7) next_S_dout = {4'b0000, fifo_data_count};
else next_S_dout = 8'h00;
end
else next_S_dout = 8'h00;
end
endmodule
'Computer > Computer Structure' 카테고리의 다른 글
DMAC - FIFO for DMAC (0) | 2013.05.26 |
---|---|
DMAC - MASTER (0) | 2013.05.26 |
DMAC - FIFO (0) | 2013.05.26 |
DMAC - Register File (0) | 2013.05.26 |
DMAC - Bus (0) | 2013.05.26 |