Line 1... |
Line 1... |
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// OCIDEC-1 ATA/ATAPI-5 Controller ////
|
//// OCIDEC-1 ATA/ATAPI-5 Controller ////
|
//// Main Controller ////
|
//// Top Level ////
|
//// ////
|
//// ////
|
//// Author: Richard Herveille ////
|
//// Author: Richard Herveille ////
|
//// richard@asics.ws ////
|
//// richard@asics.ws ////
|
//// www.asics.ws ////
|
//// www.asics.ws ////
|
//// ////
|
//// ////
|
Line 33... |
Line 33... |
//// ////
|
//// ////
|
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
|
|
// CVS Log
|
// CVS Log
|
//
|
//
|
// $Id: atahost_top.v,v 1.6 2002-02-16 10:42:17 rherveille Exp $
|
// $Id: atahost_top.v,v 1.7 2002-02-18 14:25:43 rherveille Exp $
|
//
|
//
|
// $Date: 2002-02-16 10:42:17 $
|
// $Date: 2002-02-18 14:25:43 $
|
// $Revision: 1.6 $
|
// $Revision: 1.7 $
|
// $Author: rherveille $
|
// $Author: rherveille $
|
// $Locker: $
|
// $Locker: $
|
// $State: Exp $
|
// $State: Exp $
|
//
|
//
|
// Change History:
|
// Change History:
|
Line 51... |
Line 51... |
// rev.: 1.4 July 26th, 2001. Fixed non-blocking assignments.
|
// rev.: 1.4 July 26th, 2001. Fixed non-blocking assignments.
|
// rev.: 1.5 August 15th, 2001. Changed port-names to conform to new OpenCores naming-convention.
|
// rev.: 1.5 August 15th, 2001. Changed port-names to conform to new OpenCores naming-convention.
|
// rev.: 1.6 October 15th, 2001. Removed ata_defines file. Changed define statement to parameter
|
// rev.: 1.6 October 15th, 2001. Removed ata_defines file. Changed define statement to parameter
|
//
|
//
|
// $Log: not supported by cvs2svn $
|
// $Log: not supported by cvs2svn $
|
|
// Revision 1.6 2002/02/16 10:42:17 rherveille
|
|
// Added disclaimer
|
|
// Added CVS information
|
|
// Changed core for new internal counter libraries (synthesis fixes).
|
|
//
|
//
|
//
|
//
|
//
|
//
|
//
|
|
|
/////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////
|
Line 134... |
Line 139... |
// constant declarations
|
// constant declarations
|
//
|
//
|
parameter [3:0] DeviceId = 4'h1;
|
parameter [3:0] DeviceId = 4'h1;
|
parameter [3:0] RevisionNo = 4'h0;
|
parameter [3:0] RevisionNo = 4'h0;
|
|
|
`define ATA_ATA_ADR wb_adr_i[6]
|
|
`define ATA_CTRL_REG 4'b0000
|
|
`define ATA_STAT_REG 4'b0001
|
|
`define ATA_PIO_CMD 4'b0010
|
|
|
|
//
|
//
|
// Variable declarations
|
// Variable declarations
|
//
|
//
|
|
|
// registers
|
// registers
|
wire IDEctrl_IDEen, IDEctrl_rst;
|
wire IDEctrl_IDEen, IDEctrl_rst;
|
reg [ 7:0] PIO_cmdport_T1, PIO_cmdport_T2, PIO_cmdport_T4, PIO_cmdport_Teoc;
|
wire [ 7:0] PIO_cmdport_T1, PIO_cmdport_T2, PIO_cmdport_T4, PIO_cmdport_Teoc;
|
wire PIO_cmdport_IORDYen;
|
wire PIO_cmdport_IORDYen;
|
reg [31:0] CtrlReg; // control register
|
|
|
|
wire PIOack;
|
wire PIOack;
|
wire [15:0] PIOq;
|
wire [15:0] PIOq;
|
|
|
wire [31:0] stat;
|
|
|
|
wire irq; // ATA bus IRQ signal
|
wire irq; // ATA bus IRQ signal
|
|
|
|
|
/////////////////
|
/////////////////
|
// Module body //
|
// Module body //
|
/////////////////
|
/////////////////
|
|
|
// generate asynchronous reset level
|
// generate asynchronous reset level
|
// arst_signal is either a wire or a NOT-gate
|
// arst_signal is either a wire or a NOT-gate
|
wire arst_signal = arst_i ^ ARST_LVL;
|
wire arst_signal = arst_i ^ ARST_LVL;
|
|
|
// generate bus cycle / address decoder
|
//
|
wire w_acc = &wb_sel_i[1:0]; // word access
|
// hookup wishbone slave
|
wire dw_acc = &wb_sel_i; // double word access
|
//
|
|
atahost_wb_slave #(DeviceId, RevisionNo, PIO_mode0_T1,
|
// bus error
|
PIO_mode0_T2, PIO_mode0_T4, PIO_mode0_Teoc, 0, 0, 0)
|
wire berr = `ATA_ATA_ADR ? !w_acc : !dw_acc;
|
u0 (
|
|
// WISHBONE SYSCON signals
|
// PIO accesses at least 16bit wide
|
.clk_i(wb_clk_i),
|
wire PIOsel = wb_cyc_i & wb_stb_i & `ATA_ATA_ADR & w_acc;
|
.arst_i(arst_signal),
|
|
.rst_i(wb_rst_i),
|
// CON accesses only 32bit wide
|
|
wire CONsel = wb_cyc_i & wb_stb_i & !(`ATA_ATA_ADR) & dw_acc;
|
// WISHBONE SLAVE signals
|
|
.cyc_i(wb_cyc_i),
|
// generate registers
|
.stb_i(wb_stb_i),
|
|
.ack_o(wb_ack_o),
|
// generate register select signals
|
.rty_o(),
|
wire sel_ctrl = CONsel & wb_we_i & (wb_adr_i == `ATA_CTRL_REG);
|
.err_o(wb_err_o),
|
wire sel_stat = CONsel & wb_we_i & (wb_adr_i == `ATA_STAT_REG);
|
.adr_i(wb_adr_i),
|
wire sel_PIO_cmdport = CONsel & wb_we_i & (wb_adr_i == `ATA_PIO_CMD);
|
.dat_i(wb_dat_i),
|
// reserved 0x03-0x0f --
|
.dat_o(wb_dat_o),
|
|
.sel_i(wb_sel_i),
|
// generate control register
|
.we_i(wb_we_i),
|
always@(posedge wb_clk_i or negedge arst_signal)
|
.inta_o(wb_inta_o),
|
if (~arst_signal)
|
|
begin
|
// PIO control inputs
|
CtrlReg[31:1] <= 0;
|
.PIOsel(PIOsel),
|
CtrlReg[0] <= 1'b1; // set reset bit (ATA-RESETn line)
|
// PIOtip is only asserted during a PIO transfer (No shit! ;)
|
end
|
// Since it is impossible to read the status register and access the PIO registers at the same time
|
else if (wb_rst_i)
|
// this bit is useless (besides using-up resources)
|
begin
|
.PIOtip(1'b0),
|
CtrlReg[31:1] <= 0;
|
.PIOack(PIOack),
|
CtrlReg[0] <= 1'b1; // set reset bit (ATA-RESETn line)
|
.PIOq(PIOq),
|
end
|
.PIOpp_full(1'b0), // OCIDEC-1 does not support PIO-write pingpong, negate signal
|
else if (sel_ctrl)
|
.irq(irq),
|
CtrlReg <= wb_dat_i;
|
|
|
// DMA control inputs (negate all of them, OCIDEC-1 does not support DMA)
|
// assign bits
|
.DMAsel(),
|
assign IDEctrl_IDEen = CtrlReg[7];
|
.DMAtip(1'b0),
|
assign PIO_cmdport_IORDYen = CtrlReg[1];
|
.DMAack(1'b0),
|
assign IDEctrl_rst = CtrlReg[0];
|
.DMARxEmpty(1'b0),
|
|
.DMATxFull(1'b0),
|
|
.DMA_dmarq(1'b0),
|
// generate status register clearable bits
|
.DMAq(32'h0),
|
reg dirq, int;
|
|
|
// outputs
|
always@(posedge wb_clk_i or negedge arst_signal)
|
// control register outputs
|
if (~arst_signal)
|
.IDEctrl_rst(IDEctrl_rst),
|
begin
|
.IDEctrl_IDEen(IDEctrl_IDEen),
|
int <= 1'b0;
|
.IDEctrl_FATR0(),
|
dirq <= 1'b0;
|
.IDEctrl_FATR1(),
|
end
|
.IDEctrl_ppen(),
|
else if (wb_rst_i)
|
|
begin
|
.DMActrl_DMAen(),
|
int <= 1'b0;
|
.DMActrl_dir(),
|
dirq <= 1'b0;
|
.DMActrl_BeLeC0(),
|
end
|
.DMActrl_BeLeC1(),
|
else
|
|
begin
|
// CMD port timing registers
|
int <= (int | (irq & !dirq)) & !(sel_stat & !wb_dat_i[0]);
|
.PIO_cmdport_T1(PIO_cmdport_T1),
|
dirq <= irq;
|
.PIO_cmdport_T2(PIO_cmdport_T2),
|
end
|
.PIO_cmdport_T4(PIO_cmdport_T4),
|
|
.PIO_cmdport_Teoc(PIO_cmdport_Teoc),
|
// assign status bits
|
.PIO_cmdport_IORDYen(PIO_cmdport_IORDYen),
|
assign stat[31:28] = DeviceId; // set Device ID
|
|
assign stat[27:24] = RevisionNo; // set revision number
|
// data-port0 timing registers
|
assign stat[23: 1] = 0; // --clear unused bits--
|
.PIO_dport0_T1(),
|
// Although stat[7]=PIOtip this bit is zero, because it is impossible
|
.PIO_dport0_T2(),
|
// to read the status register and access the PIO registers at the same time.
|
.PIO_dport0_T4(),
|
assign stat[0] = int;
|
.PIO_dport0_Teoc(),
|
|
.PIO_dport0_IORDYen(),
|
|
|
// generate PIO compatible / command-port timing register
|
// data-port1 timing registers
|
always@(posedge wb_clk_i or negedge arst_signal)
|
.PIO_dport1_T1(),
|
if (~arst_signal)
|
.PIO_dport1_T2(),
|
begin
|
.PIO_dport1_T4(),
|
PIO_cmdport_T1 <= PIO_mode0_T1;
|
.PIO_dport1_Teoc(),
|
PIO_cmdport_T2 <= PIO_mode0_T2;
|
.PIO_dport1_IORDYen(),
|
PIO_cmdport_T4 <= PIO_mode0_T4;
|
|
PIO_cmdport_Teoc <= PIO_mode0_Teoc;
|
// DMA device0 timing registers
|
end
|
.DMA_dev0_Tm(),
|
else if (wb_rst_i)
|
.DMA_dev0_Td(),
|
begin
|
.DMA_dev0_Teoc(),
|
PIO_cmdport_T1 <= PIO_mode0_T1;
|
|
PIO_cmdport_T2 <= PIO_mode0_T2;
|
// DMA device1 timing registers
|
PIO_cmdport_T4 <= PIO_mode0_T4;
|
.DMA_dev1_Tm(),
|
PIO_cmdport_Teoc <= PIO_mode0_Teoc;
|
.DMA_dev1_Td(),
|
end
|
.DMA_dev1_Teoc()
|
else if(sel_PIO_cmdport)
|
);
|
begin
|
|
PIO_cmdport_T1 <= wb_dat_i[ 7: 0];
|
|
PIO_cmdport_T2 <= wb_dat_i[15: 8];
|
|
PIO_cmdport_T4 <= wb_dat_i[23:16];
|
|
PIO_cmdport_Teoc <= wb_dat_i[31:24];
|
|
end
|
|
|
|
|
|
//
|
//
|
// hookup controller section
|
// hookup controller section
|
//
|
//
|
Line 295... |
Line 287... |
.DIOWn(diown_pad_o),
|
.DIOWn(diown_pad_o),
|
.IORDY(iordy_pad_i),
|
.IORDY(iordy_pad_i),
|
.INTRQ(intrq_pad_i)
|
.INTRQ(intrq_pad_i)
|
);
|
);
|
|
|
//
|
|
// generate WISHBONE interconnect signals
|
|
//
|
|
reg [31:0] Q;
|
|
|
|
// generate acknowledge signal
|
|
assign wb_ack_o = PIOack | CONsel;
|
|
|
|
// generate error signal
|
|
assign wb_err_o = wb_cyc_i & wb_stb_i & berr;
|
|
|
|
// generate interrupt signal
|
|
assign wb_inta_o = stat[0];
|
|
|
|
// generate output multiplexor
|
|
always@(wb_adr_i or CtrlReg or stat or PIO_cmdport_T1 or PIO_cmdport_T2 or PIO_cmdport_T4 or PIO_cmdport_Teoc)
|
|
case (wb_adr_i[5:2]) // synopsis full_case parallel_case
|
|
4'b0000: Q = CtrlReg;
|
|
4'b0001: Q = stat;
|
|
4'b0010: Q = {PIO_cmdport_Teoc, PIO_cmdport_T4, PIO_cmdport_T2, PIO_cmdport_T1};
|
|
default: Q = 0;
|
|
endcase
|
|
|
|
// assign DAT_O output
|
|
assign wb_dat_o = `ATA_ATA_ADR ? {16'h0000, PIOq} : Q;
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|