본문 바로가기

Computer/Computer Structure

DMAC - SLAVE

 #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