Subversion Repositories ngs

Rev

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

  1. // part of NeoGS flash programmer project (c) 2014 lvd^NedoPC
  2. //
  3. // zxbus controller
  4.  
  5. module zxbus
  6. (
  7.         input  wire clk,
  8.         input  wire rst_n,
  9.        
  10.         inout  wire [7:0] zxid, // zxbus DATA BUS in/out [7:0]
  11.         input  wire [7:0] zxa,  // zxbus ADDRESS 7-0 in [7:0]
  12.         input  wire       zxiorq_n,
  13.         input  wire       zxmreq_n,
  14.         input  wire       zxrd_n,
  15.         input  wire       zxwr_n,
  16.         output wire       zxblkiorq_n, // active low - signal to generate IORQGE
  17.         output reg        zxbusin,    // controls 74hct245 buffer direction (1 - input from bus, 0 - output to zx)
  18.         output reg        zxbusena_n, // 74hct245 buffer enable signal
  19.  
  20.         output reg        init, // positive pulse to cause reset/init to all board
  21.         input  wire       init_in_progress, // 1 while init in progress
  22.  
  23.         output reg        led, // LED state
  24.  
  25.         output reg        autoinc_ena, // enable autoincrement
  26.  
  27.         output reg        wr_addr,   // to ROM controller
  28.         output reg        wr_data,   //
  29.         output reg        rd_data,   //
  30.         output reg  [7:0] wr_buffer, //
  31.         input  wire [7:0] rd_buffer  //
  32. );
  33.  
  34.         wire iowr = ~(zxiorq_n | zxwr_n);
  35.         wire iord = ~(zxiorq_n | zxrd_n);
  36.  
  37.         reg [2:0] iowr_r;
  38.         reg [2:0] iord_r;
  39.  
  40.         wire iowr_begin, iowr_end;
  41.         wire iord_begin, iord_end;
  42.        
  43.         wire io_begin, io_end;
  44.  
  45.         wire addr_ok;
  46.  
  47.         reg wrr;
  48.  
  49.  
  50.         wire [1:0] regsel;
  51.  
  52.  
  53.         reg [7:0] read_data;
  54.  
  55.  
  56.         reg        zxid_oe;
  57.         reg  [7:0] zxid_out;
  58.         wire [7:0] zxid_in;
  59.  
  60.  
  61.  
  62.         reg [8:0] test_reg;
  63.         reg [7:0] test_reg_pre;
  64.         reg       test_reg_write;
  65.  
  66.  
  67.  
  68.  
  69.  
  70.         // register select (one of 4)
  71.         assign regsel[1:0] = { zxa[7], zxa[3] };
  72.  
  73.  
  74.  
  75.         // addr decode
  76.         assign addr_ok = (zxa==8'h33) || (zxa==8'h3B) || (zxa==8'hB3) || (zxa==8'hBB);
  77.  
  78.         // IORQGE
  79.         assign zxblkiorq_n = ~addr_ok;
  80.  
  81.  
  82.         // internal data bus control
  83.         assign zxid = zxid_oe ? zxid_out : 8'bZZZZ_ZZZZ;
  84.         //
  85.         assign zxid_in = zxid;
  86.  
  87.  
  88.  
  89.         // resync strobes
  90.         always @(posedge clk)
  91.         begin
  92.                 iowr_r[2:0] <= { iowr_r[1:0], iowr };
  93.                 iord_r[2:0] <= { iord_r[1:0], iord };
  94.         end
  95.         //
  96.         assign iowr_begin = iowr_r[1] && !iowr_r[2];
  97.         assign iord_begin = iord_r[1] && !iord_r[2];
  98.         //
  99.         assign iowr_end = !iowr_r[1] && iowr_r[2];
  100.         assign iord_end = !iord_r[1] && iord_r[2];
  101.         //
  102.         assign io_begin = iowr_begin || iord_begin;
  103.         assign io_end   = iowr_end   || iord_end;
  104.  
  105.  
  106.         // control ext bus buffer
  107.         always @(posedge clk, negedge rst_n)
  108.         if( !rst_n )
  109.         begin
  110.                 zxbusin    <= 1'b1;
  111.                 zxbusena_n <= 1'b1;
  112.         end
  113.         else if( addr_ok && io_begin )
  114.         begin
  115.                 zxbusin    <= ~iord_begin;
  116.                 zxbusena_n <= 1'b0;
  117.         end
  118.         else if( io_end )
  119.         begin
  120.                 zxbusena_n <= 1'b1;
  121.         end
  122.  
  123.         // control int bus buffer
  124.         always @(posedge clk, negedge rst_n)
  125.         if( !rst_n )
  126.         begin
  127.                 zxid_oe <= 1'b0;
  128.         end
  129.         else if( addr_ok && io_begin )
  130.         begin
  131.                 zxid_oe <= iord_begin;
  132.         end
  133.         else if( io_end )
  134.         begin
  135.                 zxid_oe <= 1'b0;
  136.         end
  137.  
  138.         // internal write strobe
  139.         always @(posedge clk, negedge rst_n)
  140.         if( !rst_n )
  141.                 wrr <= 1'b0;
  142.         else
  143.                 wrr <= addr_ok && iowr_begin;
  144.  
  145.  
  146.  
  147.         // write to 33 (init/ctrl reg)
  148.         //
  149.         always @(posedge clk, negedge rst_n)
  150.         if( !rst_n )
  151.                 led <= 1'b0;
  152.         else if( init )
  153.                 led <= 1'b0;
  154.         else if( wrr && regsel==2'b00 && zxid[6] )
  155.                 led <= ~led;
  156.         //
  157.         always @(posedge clk, negedge rst_n)
  158.         if( !rst_n )
  159.                 init <= 1'b0;
  160.         else if( wrr && regsel==2'b00 && zxid[7] )
  161.                 init <= 1'b1;
  162.         else
  163.                 init <= 1'b0;
  164.         //
  165.         always @(posedge clk, negedge rst_n)
  166.         if( !rst_n )
  167.                 autoinc_ena <= 1'b0;
  168.         else if( wrr && regsel==2'b00 )
  169.                 autoinc_ena <= zxid[5];
  170.  
  171.  
  172.         // write to 3B (test reg)
  173.         always @(posedge clk, negedge rst_n)
  174.         if( !rst_n )
  175.         begin
  176.                 test_reg <= 9'd0;
  177.         end
  178.         else if( init )
  179.         begin
  180.                 test_reg <= 9'd0;
  181.         end
  182.         else if( test_reg_write )
  183.         begin
  184.                 test_reg[8:0] <= { (~test_reg_pre[7:0]), test_reg[8] };
  185.         end
  186.         //
  187.         always @(posedge clk)
  188.         if( wrr && regsel==2'b01 )
  189.         begin
  190.                 test_reg_pre <= zxid_in;
  191.                 test_reg_write <= 1'b1;
  192.         end
  193.         else
  194.         begin
  195.                 test_reg_write <= 1'b0;
  196.         end
  197.  
  198.  
  199.         // write to B3 (addr reg)
  200.         always @(posedge clk)
  201.         if( wrr && regsel==2'b10 )
  202.                 wr_addr <= 1'b1;
  203.         else
  204.                 wr_addr <= 1'b0;
  205.  
  206.         // write to BB (data reg)
  207.         always @(posedge clk)
  208.         if( wrr && regsel==2'b11 )
  209.                 wr_data <= 1'b1;
  210.         else
  211.                 wr_data <= 1'b0;
  212.  
  213.         // read from BB (data reg)
  214.         always @(posedge clk)
  215.         if( addr_ok && regsel==2'b11 && iord_begin )
  216.                 rd_data <= 1'b1;
  217.         else
  218.                 rd_data <= 1'b0;
  219.  
  220.         // write data for B3 and BB
  221.         always @(posedge clk)
  222.         if( wrr && regsel[1]==1'b1 )
  223.                 wr_buffer <= zxid_in;
  224.  
  225.  
  226.         // ports read
  227.         always @*
  228.         case( regsel )
  229.                 2'b00:   read_data = { init_in_progress, 7'd0 };
  230.                 2'b01:   read_data = test_reg[7:0];
  231.                 //2'b10:   read_data <= рег адреса (НОЛЬ!)
  232.                 2'b11:   read_data = rd_buffer;
  233.                 default: read_data = 8'd0;
  234.         endcase
  235.         //
  236.         always @(posedge clk)
  237.         if( addr_ok && iord_begin )
  238.                 zxid_out <= read_data;
  239.  
  240.  
  241.  
  242. endmodule
  243.  
  244.