Subversion Repositories ngs

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed | ?url?

  1. // part of NeoGS project
  2. //
  3. // (c) NedoPC 2007-2009
  4. //
  5. // ZX dma controller
  6. //
  7. // includes dma address regs, dma control reg
  8. //
  9.  
  10. module dma_zx(
  11.  
  12.         input clk,
  13.         input rst_n,
  14.  
  15.  
  16.         // ZXBUS-related signals
  17.  
  18.         input dma_zxread_toggle;
  19.         input dma_zxwrite_toggle;
  20.  
  21.         output reg dma_reswait_n;
  22.  
  23.         input      [7:0] dma_data_written;
  24.         output reg [7:0] dma_data_toberead;
  25.  
  26.  
  27.         // different global & control signals
  28.  
  29.         output reg dma_on;
  30.  
  31.  
  32.         // signals from ports.v
  33.  
  34.         input      [7:0] din;  // input and output from ports.v
  35.         output reg [7:0] dout;
  36.  
  37.         input module_select; // =1 - module selected for read-write operations from ports.v
  38.         input write_strobe; // one-cycle positive write strobe - writes to the selected registers from din
  39.  
  40.         input [1:0] regsel; // 2'b00 - high address, 2'b01 - middle address, 2'b10 - low address, 2'b11 - control register
  41.  
  42.  
  43.         // signals for DMA controller
  44.  
  45.       output reg [20:0] dma_addr;
  46.       output reg  [7:0] dma_wd;
  47.       input       [7:0] dma_rd;
  48.       output reg        dma_rnw;
  49.  
  50.       output reg dma_req;
  51.       input      dma_ack;
  52.       input      dma_done;
  53.  
  54. );
  55.  
  56.         wire zxrd,zxwr; // zx read and write indicators, =1 when zx just done the thing. must be cleared.
  57.         reg zxoldrd,zxoldwr;
  58.         reg zxclr; // clear zxrd or zxwr
  59.         reg [2:0] zxrdtgl, zxwrtgl; // syncing in dma_zx(read|write)_toggle
  60.  
  61.         //zxrd or zxwr first set to 1 when zx**tgl[2]!=zx**tgl[1], then it supported in 1 state from zxold** flipflop
  62.         //by asserting zxclr=1 for 1 cycle, zxold** are both cleared.
  63.  
  64.  
  65.         localparam _HAD = 2'b00; // high address
  66.         localparam _MAD = 2'b01; // mid address
  67.         localparam _LAD = 2'b10; // low address
  68.         localparam _CST = 2'b11; // control and status
  69.  
  70.  
  71.  
  72.  
  73.  
  74.         // control dout bus
  75.         always @*
  76.         case( regsel[1:0] )
  77.                 _HAD: dout = { 3'b000, dma_addr[20:16] };
  78.                 _MAD: dout = dma_addr[15:8];
  79.                 _LAD: dout = dma_addr[7:0];
  80.                 _CST: dout = { dma_on, 7'bXXXXXXX };
  81.         endcase
  82.  
  83.         // ports.v write access & dma_addr control
  84.         always @(posedge clk, negedge rst_n)
  85.         if( !rst_n ) // async reset
  86.         begin
  87.                 dma_on <= 1'b0;
  88.         end
  89.         else // posedge clk
  90.         begin
  91.                 // dma_on control
  92.                 if( module_select && write_strobe && (regsel==_CST) )
  93.                         dma_on <= din[7];
  94.  
  95.                 // dma_addr control
  96.                 if( dma_ack && dma_on )
  97.                         dma_addr <= dma_addr + 20'd1; // increment on beginning of DMA transfer
  98.                 else if( module_select && write_strobe )
  99.                 begin
  100.                         if( regsel==_HAD )
  101.                                 dma_addr[20:16] <= din[4:0];
  102.                         else if( regsel==_MAD )
  103.                                 dma_addr[15:8]  <= din[7:0];
  104.                         else if( regsel==_LAD )
  105.                                 dma_addr[7:0]   <= din[7:0];
  106.                 end
  107.         end
  108.  
  109.         // dma_zx(read|write)_toggle syncing in and zxrd/zxwr strobes
  110.         always @(posedge clk,negedge rst_n)
  111.         if( !rst_n )
  112.         begin
  113.                 zxoldrd <= 1'b0;
  114.                 zxoldwr <= 1'b0;
  115.         end
  116.         else //posedge clk
  117.         begin
  118.                 if( dma_on )
  119.                 begin
  120.                         if( zxrdtgl[2] != zxrdtgl[1] )
  121.                                 zxoldrd <= 1'b1;
  122.                         else if( zxclr )
  123.                                 zxoldrd <= 1'b0;
  124.  
  125.                         if( zxwrtgl[2] != zxwrtgl[1] )
  126.                                 zxoldwr <= 1'b1;
  127.                         else if( zxclr )
  128.                                 zxoldwr <= 1'b0;
  129.                 end
  130.                 else
  131.                 begin
  132.                         zxoldrd <= 1'b0;
  133.                         zxoldwr <= 1'b0;
  134.                 end
  135.         end
  136.  
  137.         always @(posedge clk)
  138.         begin
  139.                 zxrdtgl[2:0] <= { zxrdtgl[1:0], dma_zxread_toggle  };
  140.                 zxwrtgl[2:0] <= { zxwrtgl[1:0], dma_zxwrite_toggle };
  141.         end
  142.  
  143.         assign zxrd = ( zxrdtgl[2] != zxrdtgl[1] ) | zxoldrd;
  144.         assign zxwr = ( zxwrtgl[2] != zxwrtgl[1] ) | zxoldwr;
  145.  
  146.  
  147.  
  148.  
  149.  
  150. endmodule
  151.  
  152.