OpenCores
URL https://opencores.org/ocsvn/vg_z80_sbc/vg_z80_sbc/trunk

Subversion Repositories vg_z80_sbc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 11 to Rev 12
    Reverse comparison

Rev 11 → Rev 12

/trunk/rtl/wb_vhdfd.v
0,0 → 1,361
//////////////////////////////////////////////////////////////////////
//// ////
//// $Id: wb_vhdfd.v,v 1.1 2008-12-08 02:12:03 hharte Exp $ ////
//// wb_vhdfd.v - Vector Graphic HD/FD Disk Controller with ////
//// Wishbone Slave interface. ////
//// ////
//// This file is part of the Vector Graphic Z80 SBC Project ////
//// http://www.opencores.org/projects/vg_z80_sbc/ ////
//// ////
//// Author: ////
//// - Howard M. Harte (hharte@opencores.org) ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2008 Howard M. Harte ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
 
//| Write Read
//| C0 - CTRL0 STATUS0
//| C1 - CTRL1 STATUS1
//| C2 - DATA_PORT DATA_PORT
//| C3 - START RESET
 
`define CTRL0 4'b0001
`define CTRL1 4'b0010
`define DATA_PORT 4'b0100
`define START_CMD 4'b1000
 
`define STATUS0 4'b0001
`define STATUS1 4'b0010
`define RESET 4'b1000
 
module wb_vhdfd (clk_i, nrst_i, wbs_adr_i, wbs_dat_o, wbs_dat_i, wbs_sel_i, wbs_we_i,
wbs_stb_i, wbs_cyc_i, wbs_ack_o,
flash_adr_o,flash_dat_o, flash_dat_i, flash_oe, flash_ce, flash_we
);
 
input clk_i;
input nrst_i;
input [2:0] wbs_adr_i;
output reg [8:0] wbs_dat_o;
input [8:0] wbs_dat_i;
input [3:0] wbs_sel_i;
input wbs_we_i;
input wbs_stb_i;
input wbs_cyc_i;
output reg wbs_ack_o;
 
// FLASH Interface
output [23:0] flash_adr_o;
output [7:0] flash_dat_o;
input [7:0] flash_dat_i;
output flash_oe;
output flash_ce;
output flash_we;
 
reg [7:0] ctrl0;
reg [7:0] ctrl1;
reg start_cmd;
reg [10:0] curr_track[0:3];
reg [8:0] sector_ram_ptr;
 
// CTRL0 bits
wire [1:0] ds = ctrl0[1:0];
wire [2:0] hds = ctrl0[4:2];
wire step_track = ctrl0[5];
wire step_dir = ctrl0[6];
 
// CTRL1 bits
wire [4:0] sector = ctrl1[4:0];
wire disk_read = ctrl1[5];
 
// STATUS0 bits
wire wp = 1'b1; // Write protected, controller can't write to FLASH
wire track0 = (curr_track[ds] == 11'h0);
 
// STATUS1 bits
wire fd_sel = (ds != 2'b00); // Bit 0, floppy disk selected
wire ctrl_busy; // Bit 1, Controller is busy.
wire motor_on = fd_sel; // Bit 2, Motor On
wire hd_type = 1'b1; // Bit 3, Hard Disk Type, 1=10MB, 0=5MB
 
 
wire [7:0] sector_ram_dat_o;
 
wire [8:0] disk_adr;
wire [7:0] disk_dat_o;
wire [7:0] disk_dat_i;
wire disk_ram_wr;
 
// generate wishbone register bank writes
wire wbs_acc = wbs_cyc_i & wbs_stb_i; // WISHBONE access
wire wbs_wr = wbs_acc & wbs_we_i & !wbs_ack_o; // WISHBONE write access
wire wbs_rd = wbs_acc & !wbs_we_i & !wbs_ack_o; // WISHBONE read access
 
wire sector_ram_wr = (wbs_wr & (wbs_adr_i == 3'h2));
 
always @(posedge clk_i or negedge nrst_i)
if (~nrst_i) // reset registers
begin
sector_ram_ptr <= 9'h0;
start_cmd <= 1'b0;
curr_track[0] <= 11'h010;
curr_track[1] <= 11'h020;
curr_track[2] <= 11'h030;
curr_track[3] <= 11'h040;
end
else begin
if(ctrl_busy == 1'b1) begin
start_cmd <= 1'b0;
end
if(wbs_wr) // wishbone write cycle
case(wbs_adr_i)
3'h0: begin // CTRL0
ctrl0 <= wbs_dat_i;
if(wbs_dat_i[5] == 1'b1) begin // STEP
if(wbs_dat_i[6] == 1'b1) begin // Step In
curr_track[ds] <= curr_track[ds] + 11'h1;
end
else begin // Step Out
curr_track[ds] <= curr_track[ds] - 11'h1;
end
end
end
3'h1: begin // CTRL1
ctrl1 <= wbs_dat_i;
end
3'h2: begin // DATA_PORT
sector_ram_ptr <= sector_ram_ptr + 9'h001;
end
3'h3: begin // START
start_cmd <= 1'b1;
end
endcase
if(wbs_rd) begin
case(wbs_adr_i) // Wishbone Read, decode byte enables to determine register offset.
3'h0: begin // STATUS0 Register
wbs_dat_o <= {2'b11, 3'b000, track0, 1'b0,wp };
end
3'h1: begin // STATUS1 Register
wbs_dat_o <= {4'hF, hd_type, motor_on, ctrl_busy, fd_sel };
end
3'h2: begin // DATA_PORT
wbs_dat_o <= sector_ram_dat_o;
sector_ram_ptr <= sector_ram_ptr + 9'h001;
end
3'h3: begin // RESET
wbs_dat_o <= 8'h0F;
sector_ram_ptr <= 9'h0;
start_cmd <= 1'b0;
end
3'h4: begin // DIAG0
wbs_dat_o <= sector_ram_ptr[7:0];
end
3'h5: begin // DIAG1
wbs_dat_o <= disk_adr[7:0];
end
3'h6: begin // DIAG2
wbs_dat_o <= { 6'h00, start_cmd, ds };
end
3'h7: begin // DIAG3
wbs_dat_o <= { curr_track[ds][7:0] };
end
endcase
end
end
 
//
// generate ack_o
always @(posedge clk_i)
wbs_ack_o <= #1 wbs_acc & !wbs_ack_o;
 
// Instantiate the module
vhdfd_disk disks (
.clk_i(clk_i),
.nrst_i(nrst_i),
.ds(ds),
.hds(hds),
.curr_track(curr_track[ds]),
.sector(sector),
.start_cmd(start_cmd),
.disk_read(disk_read),
.ctrl_busy(ctrl_busy),
.disk_adr(disk_adr),
.disk_dat_o(disk_dat_o),
.disk_dat_i(disk_dat_i),
.disk_ram_wr(disk_ram_wr),
.flash_adr_o(flash_adr_o),
.flash_dat_o(flash_dat_o),
.flash_dat_i(flash_dat_i),
.flash_oe(flash_oe),
.flash_ce(flash_ce),
.flash_we(flash_we));
 
// Instantiate the Sector RAM (512 bytes)
// synthesis attribute ram_style of sector_ram is block
vga_dpram #(
.mem_file_name("none"),
.adr_width(9),
.dat_width(8)
) sector_ram (
.clk1(clk_i),
.clk2(clk_i),
//
.adr0(sector_ram_ptr),
.dout0(sector_ram_dat_o),
.din0(wbs_dat_i),
.we0(sector_ram_wr),
//
.adr1(disk_adr),
.dout1(disk_dat_i),
.din1(disk_dat_o),
.we1(disk_ram_wr)
);
 
endmodule
 
module vhdfd_disk (clk_i, nrst_i, ds, hds, curr_track, sector, start_cmd, disk_read, ctrl_busy,
disk_adr, disk_dat_o, disk_dat_i, disk_ram_wr,
flash_adr_o,flash_dat_o, flash_dat_i, flash_oe, flash_ce, flash_we
);
 
input clk_i;
input nrst_i;
input [1:0] ds;
input [2:0] hds;
input [10:0] curr_track;
input [4:0] sector;
input start_cmd;
input disk_read;
output reg ctrl_busy;
output reg [8:0] disk_adr;
output reg [7:0] disk_dat_o;
input [7:0] disk_dat_i;
output reg disk_ram_wr;
 
// FLASH Interface
output [23:0] flash_adr_o;
output [7:0] flash_dat_o;
input [7:0] flash_dat_i;
output flash_oe;
output flash_ce;
output flash_we;
reg [3:0] waitstate;
 
reg [13:0] state;
 
wire [23:0] sector_flash_adr;
 
assign sector_flash_adr = { 3'b000, hds[0], curr_track[6:0], sector[3:0], 9'h0 };
 
`define DISK_ST_IDLE 14'h000 // Disk Idle
`define DISK_ST_READ_SECTOR 14'h001 // Disk Read Sector
`define DISK_ST_WRITE_SECTOR 14'h002 // Disk Write Sector
`define DISK_ST_READ_WAIT 14'h004 // Disk Waitstate for FLASH read
`define DISK_ST_READ_WAIT2 14'h008 // Disk Waitstate for FLASH read
`define DISK_ST_READ_WAIT3 14'h010 // Disk Waitstate for FLASH read
`define DISK_ST_READ_WAIT4 14'h020 // Disk Waitstate for FLASH read
 
always @(posedge clk_i or negedge nrst_i)
if (~nrst_i) // reset registers
begin
ctrl_busy <= 1'b0;
disk_adr <= 9'h000;
state <= `DISK_ST_IDLE;
end
else begin
case(state)
`DISK_ST_IDLE:
begin
if(start_cmd & disk_read) begin // Wishbone access starts LPC transaction
state <= `DISK_ST_READ_SECTOR;
ctrl_busy <= 1'b1;
end
else if(start_cmd & !disk_read) begin
state <= `DISK_ST_WRITE_SECTOR;
ctrl_busy <= 1'b1;
end
else begin
state <= `DISK_ST_IDLE;
ctrl_busy <= 1'b0;
disk_adr <= 9'h000;
end
end
`DISK_ST_READ_SECTOR:
begin
if(disk_adr != 9'h1FF) begin
disk_ram_wr <= 1'b1;
disk_adr <= disk_adr + 9'h001;
state <= `DISK_ST_READ_WAIT;
end
else begin
disk_ram_wr <= 1'b0;
state <= `DISK_ST_IDLE;
end
end
`DISK_ST_READ_WAIT:
begin
state <= `DISK_ST_READ_WAIT2;
end
`DISK_ST_READ_WAIT2:
begin
state <= `DISK_ST_READ_WAIT3;
end
`DISK_ST_READ_WAIT3:
begin
state <= `DISK_ST_READ_WAIT4;
end
`DISK_ST_READ_WAIT4:
begin
if(disk_adr > 9'h10E)
disk_dat_o <= 8'h00;
else
disk_dat_o <= flash_dat_i;
state <= `DISK_ST_READ_SECTOR;
end
`DISK_ST_WRITE_SECTOR:
begin
if(disk_adr != 9'h1FF) begin
disk_ram_wr <= 1'b0;
disk_adr <= disk_adr + 9'h001;
end
else begin
state <= `DISK_ST_IDLE;
end
end
endcase
end
 
assign flash_adr_o = { sector_flash_adr[23:9], disk_adr[8:0] };
assign flash_oe = 1'b0;
assign flash_we = 1'b1;
assign flash_ce = 1'b0;
assign flash_dat_o = 8'hAA;
 
endmodule
trunk/rtl/wb_vhdfd.v Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.