module cpld_top ( // buffered ISA signals input isa_RESET, // ISA reset inout [15:0] isa_D, // ISA data bus (x8) input [19:0] isa_SA, // ISA system address bus (x20) input [23:17] isa_UA, // ISA address bus (x7) input isa_ALE, // ISA address latch enable input isa_SMEMWn, // ISA system memory write input isa_SMEMRn, // ISA system memory read input isa_MEMWn, // ISA memory write input isa_MEMRn, // ISA memory read input isa_IOWn, // ISA I/O write input isa_IORn, // ISA I/O read input isa_SBHEn, // ISA system byte high enable output isa_READY, // ISA ready output isa_M16n, // ISA 16-bit memory supported output isa_IO16n, // ISA 16-bit I/O supported input isa_AEN, // ISA DMA address enable output isa_ZWSn, // ISA Zero wait state enable // Misc input sys_CLK_in, // SYS 20.00 MHz external XO input sys_CFGn, // Normal (1) vs config (0) DIP SW output sys_LED_R, // Status LED Red output sys_LED_B, // Status LED Blue inout [0:6] sys_TAP, // Diagnostic TAPs // SPI flash output spi_CLK, // SPI flash clock output spi_CSn, // SPI flash chip select output spi_MOSI, // SPI flash master out slave in input spi_MISO, // SPI flash master in slave out // 64MB SDR SDRAM output [12:0] sdram_A, // 8 Kbit row/column address inout [15:0] sdram_D, // 16-bit data output sdram_CLK, // Clock output sdram_CKE, // Clock enable output [1:0] sdram_DQM, // Data qualification mask output [1:0] sdram_BA, // Bank address output sdram_CSn, // Chip select output sdram_RASn, // Row address strobe output sdram_CASn, // Column address strobe output sdram_WEn // Write enable strobe ); // Clock setup. wire sys_CLK; wire sdr_CLK; wire pll_LOCK; plla PLLA ( .CLKI (sys_CLK_in), // 20 MHz .CLKOP (sdr_CLK), // 80 MHz .CLKOS (sys_CLK), // 40 MHz .LOCK (pll_LOCK) ); wire sys_RST = isa_RESET; // Configuration wire cfg_XMS[31:0] = { 32'b0011_1111_1111_1111_0000_0000_0000_0000 }; // ISA strobe aggregation - positive logic wire isa_SMEMW = ~isa_SMEMWn; wire isa_SMEMR = ~isa_SMEMRn; wire isa_MEMW = ~isa_MEMWn; wire isa_MEMR = ~isa_MEMRn; wire isa_IOW = ~isa_IOWn; wire isa_IOR = ~isa_IORn; wire isa_SBHE = ~isa_SBHEn; wire isa_IO = (isa_IOW | isa_IOR) & !isa_AEN; wire isa_MEM = isa_SMEMW | isa_MEMW | isa_SMEMR | isa_MEMR; wire isa_WE = isa_SMEMW | isa_MEMW | isa_IOW; // ISA address propagation reg [23:17] isa_LA; always @(negedge isa_ALE) isa_LA <= isa_UA; wire [23:0] isa_A; assign isa_A[23:20] = isa_LA[23:20]; assign isa_A [19:0] = isa_SA[19:0]; wire [4:0] zero_IDX = { isa_LA[23:19] }; wire cs_XMS = cfg_XMS[ zero_IDX ]; // I/O decode logic reg [8:0] io_BASE = 9'b0010_0100_0; // 240 hex wire cs_IO = (isa_A[11:3] == io_BASE) & !isa_AEN; wire cs_EFB_adr = (isa_A[11:0] == {io_BASE, 3'b000}) & !isa_AEN; wire cs_EFB_dat = (isa_A[11:0] == {io_BASE, 3'b001}) & !isa_AEN; wire cs_SPI_cs = (isa_A[11:1] == {io_BASE, 2'b01 }) & !isa_AEN; wire cs_RES = (isa_A[11:0] == {io_BASE, 3'b100}) & !isa_AEN; wire cs_PAGE_adr = (isa_A[11:0] == {io_BASE, 3'b101}) & !isa_AEN; wire cs_PAGE_dat = (isa_A[11:1] == {io_BASE, 2'b11 }) & !isa_AEN; reg [7:0] efb_ADR; wire [7:0] efb_DAT; wire [7:0] spi_DAT; reg [7:0] res_DAT; reg [7:0] page_ADR; wire [15:0] page_DAT; wire [7:0] io_DAT = (isa_A[2:0] == 3'b000) ? efb_ADR : (isa_A[2:0] == 3'b001) ? efb_DAT : (isa_A[2:0] == 3'b010) ? spi_DAT : (isa_A[2:0] == 3'b011) ? spi_DAT : (isa_A[2:0] == 3'b100) ? res_DAT : (isa_A[2:0] == 3'b101) ? page_ADR : (isa_A[2:0] == 3'b110) ? page_DAT[7:0] : page_DAT[15:8]; always @(posedge sys_CLK or posedge sys_RST) begin if (sys_RST) begin efb_ADR <= 8'h00; res_DAT <= 8'h00; page_ADR <= 8'h00; end else begin if (cs_IO) begin end end end /* */ wire [14:0] cfg_XMS; wire cfg_WIDE; /* * Lower 1MB Page Translation * * The lower 1 MB is carved up into 4K page frames (12 bits). * There are 256 such page frames in lower memory indexed by * the upper 8 bits A[19:12]. These addresses are continually * translated through an EBR to produce a 16 bit output. Two * of the output bits are special. A frame translation enable * bit (page_EN) determines if during memory accesses, the card * should respond with a memory read or write with address * translation enable. A page read only bit (page_RO) determines * if memory writes should be blocked or not. The remaining * 14 bits forms the upper 14 bits of the translated address * when propagated forward to the SDRAM logic. * * For now this EBR is initialized to all zeros and cannot be * updated by the host. The next step is to allow the host to * update the table through indirect I/O writes (for EMS). * This will be further enhanced to save and restore the EBR * content to/from UFM pages (conventional fill). */ wire page_RO; // Output map: read-only bit wire page_EN; // Output map: memory enable bit wire [13:0] page_MAP; // Output map: target page number / bits [25:12] pagetable PAGETABLE ( .WrAddress (page_ADR), .RdAddress (isa_A[19:12]), .Data ({isa_D[7:0], isa_D[7:0]}), .ByteEn (isa_IO ? { ~isa_A[0], isa_A[0] } : 2'b11 ), .WE (isa_IOW), .RdClock (sys_CLK), .RdClockEn (1'b1), .Reset (sys_RST), .WrClock (sys_CLK), .WrClockEn (isa_IOW & cs_PAGE_dat), .Q ({page_EN, page_RO, page_MAP}) ); wire [15:0] sdr_DAT; wire sdr_ACK; sdram SDRAM ( .sdr_CLK (sdr_CLK), .sdr_RST (sys_RST), .sdr_A ({2'b00, isa_A}), .sdr_SEL (isa_A[0] ? 2'b10 : isa_SBHEn ? 2'b01 : 2'b11), .sdr_DAT_i (isa_A[0] ? { isa_D[7:0], 8'h00 } : isa_D), .sdr_DAT_o (sdr_DAT), .sdr_WE (isa_SMEMW), .sdr_ACK (sdr_ACK), .sdr_CE (cs_XMS & isa_MEM), .pad_DQ (sdram_D), .pad_A (sdram_A), .pad_BA (sdram_BA), .pad_CKE (sdram_CKE), .pad_CSn (sdram_CSn), .pad_RASn (sdram_RASn), .pad_CASn (sdram_CASn), .pad_WEn (sdram_WEn), .pad_DQM (sdram_DQM), .pad_CLK (sdram_CLK) ); simple_spi SPI ( .wb_clk (wb_clk), .wb_rst (wb_rst), .wb_adr (wb_adr[0]), .wb_dat_i (wb_dat[7:0]), .wb_dat_o (spi_DAT), .wb_we (wb_we), .wb_ack (spi_ACK), .wb_cyc (wb_cyc & spi_EN), .wb_stb (wb_stb & spi_EN), .spi_CLK (spi_CLK), .spi_CSn (spi_CSn), .spi_MISO (spi_MISO), .spi_MOSI (spi_MOSI) ); /* always @(*) begin case (zero_IDX) 5'd0 : isa_ZWSn = ~cfg_XMS[0]; 5'd1 : isa_ZWSn = ~cfg_XMS[1]; 5'd2 : isa_ZWSn = ~cfg_XMS[2]; 5'd3 : isa_ZWSn = ~cfg_XMS[3]; 5'd4 : isa_ZWSn = ~cfg_XMS[4]; 5'd5 : isa_ZWSn = ~cfg_XMS[5]; 5'd6 : isa_ZWSn = ~cfg_XMS[6]; 5'd7 : isa_ZWSn = ~cfg_XMS[7]; 5'd8 : isa_ZWSn = ~cfg_XMS[8]; 5'd9 : isa_ZWSn = ~cfg_XMS[9]; 5'd10 : isa_ZWSn = ~cfg_XMS[10]; 5'd11 : isa_ZWSn = ~cfg_XMS[11]; 5'd12 : isa_ZWSn = ~cfg_XMS[12]; 5'd13 : isa_ZWSn = ~cfg_XMS[13]; 5'd14 : isa_ZWSn = ~cfg_XMS[14]; 5'd15 : isa_ZWSn = ~cfg_XMS[15]; 5'd16 : isa_ZWSn = ~cfg_XMS[16]; 5'd17 : isa_ZWSn = ~cfg_XMS[17]; 5'd18 : isa_ZWSn = ~cfg_XMS[18]; 5'd19 : isa_ZWSn = ~cfg_XMS[19]; 5'd20 : isa_ZWSn = ~cfg_XMS[20]; 5'd21 : isa_ZWSn = ~cfg_XMS[21]; 5'd22 : isa_ZWSn = ~cfg_XMS[22]; 5'd23 : isa_ZWSn = ~cfg_XMS[23]; 5'd24 : isa_ZWSn = ~cfg_XMS[24]; 5'd25 : isa_ZWSn = ~cfg_XMS[25]; 5'd26 : isa_ZWSn = ~cfg_XMS[26]; 5'd27 : isa_ZWSn = ~cfg_XMS[27]; 5'd28 : isa_ZWSn = ~cfg_XMS[28]; 5'd29 : isa_ZWSn = ~cfg_XMS[29]; 5'd30 : isa_ZWSn = ~cfg_XMS[30]; 5'd31 : isa_ZWSn = ~cfg_XMS[31]; endcase end */ /* * ISA output logic * * I'm not sure how the host interprets M16 when a single byte * odd address access is issued. However I think the logic below * is ok for all cases. We always drive D[15:8] on even memory * accesses with valid data and never support 16-bit I/O accesses. * * Only assert zero wait for XML based on backfil (pure combinatorial) */ assign isa_M16n = ~cs_MEM; assign isa_IO16n = 1'bz; assign isa_READY = cs_MEM ? sdr_ACK : cs_IO ? 1'b1 : 1'bz; assign isa_D = cs_MEM ? mem_DAT : cs_IO ? {8'hzz, io_DAT } : 16'hzzzz; assign isa_ZWSn = ~cs_XMS; endmodule