URL
https://opencores.org/ocsvn/ata/ata/trunk
Subversion Repositories ata
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 14 to Rev 15
- ↔ Reverse comparison
Rev 14 → Rev 15
/trunk/rtl/verilog/ocidec-1/atahost.v
File deleted
/trunk/rtl/verilog/ocidec-1/counter.v
File deleted
/trunk/rtl/verilog/ocidec-1/pio_tctrl.v
File deleted
/trunk/rtl/verilog/ocidec-1/controller.v
File deleted
/trunk/rtl/verilog/ocidec-1/ud_cnt.v
0,0 → 1,57
// |
// file: ud_cnt.v (universal up/down counter) |
// |
// Author: Richard Herveille |
// Rev. 1.0 June 27th, 2001. Initial Verilog release |
// Rev. 1.1 July 2nd, 2001. Fixed incomplete port list. |
// |
|
|
///////////////////////////// |
// general purpose counter // |
///////////////////////////// |
|
`include "timescale.v" |
|
module ud_cnt (clk, nReset, rst, cnt_en, ud, nld, d, q, resd, rci, rco); |
// parameter declaration |
parameter SIZE = 8; |
// inputs & outputs |
input clk; // master clock |
input nReset; // asynchronous active low reset |
input rst; // synchronous active high reset |
input cnt_en; // count enable |
input ud; // up/not down |
input nld; // synchronous active low load |
input [SIZE-1:0] d; // load counter value |
output [SIZE-1:0] q; // current counter value |
input [SIZE-1:0] resd; // initial data after/during reset |
input rci; // carry input |
output rco; // carry output |
|
// variable declarations |
reg [SIZE-1:0] Qi; // intermediate value |
wire [SIZE:0] val; // carry+result |
|
// |
// Module body |
// |
|
assign val = ud ? ( {1'b0, Qi} + rci) : ( {1'b0, Qi} - rci); |
|
always@(posedge clk or negedge nReset) |
begin |
if (~nReset) |
Qi <= #1 resd; |
else if (rst) |
Qi <= #1 resd; |
else if (~nld) |
Qi <= #1 d; |
else if (cnt_en) |
Qi <= #1 val[SIZE-1:0]; |
end |
|
// assign outputs |
assign q = Qi; |
assign rco = val[SIZE]; |
endmodule |
/trunk/rtl/verilog/ocidec-1/atahost_pio_tctrl.v
0,0 → 1,179
// |
// file: pio_tctrl.v |
// description: PIO mode timing controller for ATA controller |
// author : Richard Herveille |
// Rev. 1.0 June 27th, 2001. Initial Verilog release |
// Rev. 1.1 July 2nd, 2001. Fixed incomplete port list and some Verilog related issues. |
// Rev. 1.2 July 11th, 2001. Changed 'igo' & 'hold_go' generation. |
|
// |
/////////////////////////// |
// PIO Timing controller // |
/////////////////////////// |
// |
|
// |
// Timing PIO mode transfers |
//-------------------------------------------- |
// T0: cycle time |
// T1: address valid to DIOR-/DIOW- |
// T2: DIOR-/DIOW- pulse width |
// T2i: DIOR-/DIOW- recovery time |
// T3: DIOW- data setup |
// T4: DIOW- data hold |
// T5: DIOR- data setup |
// T6: DIOR- data hold |
// T9: address hold from DIOR-/DIOW- negated |
// Trd: Read data valid to IORDY asserted |
// Ta: IORDY setup time |
// Tb: IORDY pulse width |
// |
// Transfer sequence |
//-------------------------------- |
// 1) set address (DA, CS0-, CS1-) |
// 2) wait for T1 |
// 3) assert DIOR-/DIOW- |
// when write action present Data (timing spec. T3 always honored), enable output enable-signal |
// 4) wait for T2 |
// 5) check IORDY |
// when not IORDY goto 5 |
// when IORDY negate DIOW-/DIOR-, latch data (if read action) |
// when write, hold data for T4, disable output-enable signal |
// 6) wait end_of_cycle_time. This is T2i or T9 or (T0-T1-T2) whichever takes the longest |
// 7) start new cycle |
|
`include "timescale.v" |
|
module atahost_pio_tctrl(clk, nReset, rst, IORDY_en, T1, T2, T4, Teoc, go, we, oe, done, dstrb, DIOR, DIOW, IORDY); |
// parameter declarations |
parameter TWIDTH = 8; |
parameter PIO_MODE0_T1 = 6; // 70ns |
parameter PIO_MODE0_T2 = 28; // 290ns |
parameter PIO_MODE0_T4 = 2; // 30ns |
parameter PIO_MODE0_Teoc = 23; // 240ns |
|
// inputs & outputs |
input clk; // master clock |
input nReset; // asynchronous active low reset |
input rst; // synchronous active high reset |
|
// timing & control register settings |
input IORDY_en; // use IORDY (or not) |
input [TWIDTH-1:0] T1; // T1 time (in clk-ticks) |
input [TWIDTH-1:0] T2; // T1 time (in clk-ticks) |
input [TWIDTH-1:0] T4; // T1 time (in clk-ticks) |
input [TWIDTH-1:0] Teoc; // T1 time (in clk-ticks) |
|
// control signals |
input go; // PIO controller selected (strobe signal) |
input we; // write enable signal. 1'b0 == read, 1'b1 == write |
|
// return signals |
output oe; // output enable signal |
reg oe; |
output done; // finished cycle |
output dstrb; // data strobe, latch data (during read) |
reg dstrb; |
|
// ata signals |
output DIOR; // IOread signal, active high |
reg DIOR; |
output DIOW; // IOwrite signal, active high |
reg DIOW; |
input IORDY; // IOrDY signal |
|
|
// |
// constant declarations |
// |
// PIO mode 0 settings (@100MHz clock) |
wire [TWIDTH-1:0] T1_m0 = PIO_MODE0_T1; |
wire [TWIDTH-1:0] T2_m0 = PIO_MODE0_T2; |
wire [TWIDTH-1:0] T4_m0 = PIO_MODE0_T4; |
wire [TWIDTH-1:0] Teoc_m0 = PIO_MODE0_Teoc; |
|
// |
// variable declaration |
// |
reg busy, hold_go; |
wire igo; |
wire T1done, T2done, T4done, Teoc_done, IORDY_done; |
reg hT2done; |
|
// |
// module body |
// |
|
// generate internal go strobe |
// strecht go until ready for new cycle |
always@(posedge clk or negedge nReset) |
if (~nReset) |
begin |
busy <= 1'b0; |
hold_go <= 1'b0; |
end |
else if (rst) |
begin |
busy <= 1'b0; |
hold_go <= 1'b0; |
end |
else |
begin |
busy <= (igo | busy) & !Teoc_done; |
hold_go <= (go | (hold_go & busy)) & !igo; |
end |
|
assign igo = (go | hold_go) & !busy; |
|
// 1) hookup T1 counter |
ro_cnt #(TWIDTH) t1_cnt(.clk(clk), .nReset(nReset), .rst(rst), .cnt_en(1'b1), .go(igo), .d(T1), .id(T1_m0), .done(T1done), .q()); |
|
// 2) set (and reset) DIOR-/DIOW-, set output-enable when writing to device |
always@(posedge clk or negedge nReset) |
if (~nReset) |
begin |
DIOR <= 1'b0; |
DIOW <= 1'b0; |
oe <= 1'b0; |
end |
else if (rst) |
begin |
DIOR <= 1'b0; |
DIOW <= 1'b0; |
oe <= 1'b0; |
end |
else |
begin |
DIOR <= (!we & T1done) | (DIOR & !IORDY_done); |
DIOW <= ( we & T1done) | (DIOW & !IORDY_done); |
oe <= ( (we & igo) | oe) & !T4done; // negate oe when t4-done |
end |
|
// 3) hookup T2 counter |
ro_cnt #(TWIDTH) t2_cnt(.clk(clk), .nReset(nReset), .rst(rst), .cnt_en(1'b1), .go(T1done), .d(T2), .id(T2_m0), .done(T2done), .q()); |
|
// 4) check IORDY (if used), generate release_DIOR-/DIOW- signal (ie negate DIOR-/DIOW-) |
// hold T2done |
always@(posedge clk or negedge nReset) |
if (~nReset) |
hT2done <= 1'b0; |
else if (rst) |
hT2done <= 1'b0; |
else |
hT2done <= (T2done | hT2done) & !IORDY_done; |
|
assign IORDY_done = (T2done | hT2done) & (IORDY | !IORDY_en); |
|
// generate datastrobe, capture data at rising DIOR- edge |
always@(posedge clk) |
dstrb <= IORDY_done; |
|
// hookup data hold counter |
ro_cnt #(TWIDTH) dhold_cnt(.clk(clk), .nReset(nReset), .rst(rst), .cnt_en(1'b1), .go(IORDY_done), .d(T4), .id(T4_m0), .done(T4done), .q()); |
assign done = T4done; // placing done here provides the fastest return possible, |
// while still guaranteeing data and address hold-times |
|
// 5) hookup end_of_cycle counter |
ro_cnt #(TWIDTH) eoc_cnt(.clk(clk), .nReset(nReset), .rst(rst), .cnt_en(1'b1), .go(IORDY_done), .d(Teoc), .id(Teoc_m0), .done(Teoc_done), .q()); |
|
endmodule |
/trunk/rtl/verilog/ocidec-1/ro_cnt.v
0,0 → 1,55
// |
// Counter.v, contains 1) run-once down-counter 2) general purpose up-down riple-carry counter |
// |
// Author: Richard Herveille |
// Rev. 1.0 June 27th, 2001. Initial Verilog release |
// Rev. 1.1 July 2nd, 2001. Fixed incomplete port list. |
// |
|
/////////////////////////// |
// run-once down-counter // |
/////////////////////////// |
|
// counts D+1 cycles before generating 'DONE' |
|
`include "timescale.v" |
|
module ro_cnt (clk, nReset, rst, cnt_en, go, done, d, q, id); |
// parameter declaration |
parameter SIZE = 8; |
// inputs & outputs |
input clk; // master clock |
input nReset; // asynchronous active low reset |
input rst; // synchronous active high reset |
input cnt_en; // count enable |
input go; // load counter and start sequence |
output done; // done counting |
input [SIZE-1:0] d; // load counter value |
output [SIZE-1:0] q; // current counter value |
input [SIZE-1:0] id; // initial data after reset |
|
// variable declarations |
reg rci; |
wire nld, rco; |
|
// |
// module body |
// |
|
always@(posedge clk or negedge nReset) |
if (~nReset) |
rci <= #1 1'b0; |
else if (rst) |
rci <= #1 1'b0; |
else if (cnt_en) |
rci <= #1 (go | rci) & !rco; |
|
assign nld = !go; |
|
// hookup counter |
ud_cnt #(SIZE) cnt (.clk(clk), .nReset(nReset), .rst(rst), .cnt_en(cnt_en), |
.ud(1'b0), .nld(nld), .d(d), .q(q), .resd(id), .rci(rci), .rco(rco)); |
|
// assign outputs |
assign done = rco; |
endmodule |
/trunk/rtl/verilog/ocidec-1/atahost_top.v
0,0 → 1,269
// |
// Project: AT Atachement interface |
// ATA-3 rev7B compliant |
// Author: Richard Herveille |
// rev.: 1.0 June 29th, 2001. Initial Verilog release |
// rev.: 1.1 July 3rd, 2001. Changed 'ADR_I[5:2]' into 'ADR_I' on output multiplexor sensitivity list. |
// rev.: 1.2 July 9th, 2001. Fixed register control; registers latched data on all edge cycles instead when selected. |
// rev.: 1.3 July 11th, 2001. Fixed case sensitivity error (nRESET instead of nReset) in "controller" module declaration. |
// 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. |
|
// DeviceType: OCIDEC-1: OpenCores IDE Controller type1 |
// Features: PIO Compatible Timing |
// DeviceID: 0x01 |
// RevNo : 0x00 |
|
// |
// Host signals: |
// Reset |
// DIOR- read strobe. The falling edge enables data from device onto DD. The rising edge latches data at the host. |
// DIOW- write strobe. The rising edge latches data from DD into the device. |
// DA(2:0) 3bit binary coded adress |
// CS0- select command block registers |
// CS1- select control block registers |
|
`include "timescale.v" |
|
module atahost_top (wb_clk_i, rst_nreset_i, wb_rst_i, wb_cyc_i, wb_stb_i, wb_ack_o, wb_err_o, |
wb_adr_i, wb_dat_i, wb_dat_o, wb_sel_i, wb_we_i, wb_inta_o, |
ata_resetn_pad_o, ata_dd_pad_i, ata_dd_pad_o, ata_dd_pad_oe, ata_da_pad_o, ata_cs0n_pad_o, |
ata_cs1n_pad_o, ata_diorn_pad_o, ata_diown_pad_o, ata_iordy_pad_i, ata_intrq_pad_i); |
// |
// Parameter declarations |
// |
parameter TWIDTH = 8; // counter width |
// PIO mode 0 settings (@100MHz clock) |
parameter PIO_mode0_T1 = 6; // 70ns |
parameter PIO_mode0_T2 = 28; // 290ns |
parameter PIO_mode0_T4 = 2; // 30ns |
parameter PIO_mode0_Teoc = 23; // 240ns ==> T0 - T1 - T2 = 600 - 70 - 290 = 240 |
|
// |
// inputs & outputs |
// |
|
// WISHBONE SYSCON signals |
input wb_clk_i; // master clock in |
input rst_nreset_i; // asynchronous active low reset |
input wb_rst_i; // synchronous active high reset |
|
// WISHBONE SLAVE signals |
input wb_cyc_i; // valid bus cycle input |
input wb_stb_i; // strobe/core select input |
output wb_ack_o; // strobe acknowledge output |
output wb_err_o; // error output |
input [6:2] wb_adr_i; // A6 = '1' ATA devices selected |
// A5 = '1' CS1- asserted, '0' CS0- asserted |
// A4..A2 ATA address lines |
// A6 = '0' ATA controller selected |
input [31:0] wb_dat_i; // Databus in |
output [31:0] wb_dat_o; // Databus out |
input [ 3:0] wb_sel_i; // Byte select signals |
input wb_we_i; // Write enable input |
output wb_inta_o; // interrupt request signal |
|
// ATA signals |
output ata_resetn_pad_o; |
input [15:0] ata_dd_pad_i; |
output [15:0] ata_dd_pad_o; |
output ata_dd_pad_oe; |
output [ 2:0] ata_da_pad_o; |
output ata_cs0n_pad_o; |
output ata_cs1n_pad_o; |
|
output ata_diorn_pad_o; |
output ata_diown_pad_o; |
input ata_iordy_pad_i; |
input ata_intrq_pad_i; |
|
// |
// constant declarations |
// |
parameter [3:0] DeviceId = 4'h1; |
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 |
// |
|
// registers |
wire IDEctrl_IDEen, IDEctrl_rst; |
reg [ 7:0] PIO_cmdport_T1, PIO_cmdport_T2, PIO_cmdport_T4, PIO_cmdport_Teoc; |
wire PIO_cmdport_IORDYen; |
reg [31:0] CtrlReg; // control register |
|
wire PIOack; |
wire [15:0] PIOq; |
|
wire [31:0] stat; |
|
wire irq; // ATA bus IRQ signal |
|
///////////////// |
// Module body // |
///////////////// |
|
// generate bus cycle / address decoder |
wire w_acc = &wb_sel_i[1:0]; // word access |
wire dw_acc = &wb_sel_i; // double word access |
|
// bus error |
wire berr = `ATA_ATA_ADR ? !w_acc : !dw_acc; |
|
// PIO accesses at least 16bit wide |
wire PIOsel = wb_cyc_i & wb_stb_i & `ATA_ATA_ADR & w_acc; |
|
// CON accesses only 32bit wide |
wire CONsel = wb_cyc_i & wb_stb_i & !(`ATA_ATA_ADR) & dw_acc; |
|
// generate registers |
|
// generate register select signals |
wire sel_ctrl = CONsel & wb_we_i & (wb_adr_i == `ATA_CTRL_REG); |
wire sel_stat = CONsel & wb_we_i & (wb_adr_i == `ATA_STAT_REG); |
wire sel_PIO_cmdport = CONsel & wb_we_i & (wb_adr_i == `ATA_PIO_CMD); |
// reserved 0x03-0x0f -- |
|
// generate control register |
always@(posedge wb_clk_i or negedge rst_nreset_i) |
if (~rst_nreset_i) |
begin |
CtrlReg[31:1] <= 0; |
CtrlReg[0] <= 1'b1; // set reset bit (ATA-RESETn line) |
end |
else if (wb_rst_i) |
begin |
CtrlReg[31:1] <= 0; |
CtrlReg[0] <= 1'b1; // set reset bit (ATA-RESETn line) |
end |
else if (sel_ctrl) |
CtrlReg <= wb_dat_i; |
|
// assign bits |
assign IDEctrl_IDEen = CtrlReg[7]; |
assign PIO_cmdport_IORDYen = CtrlReg[1]; |
assign IDEctrl_rst = CtrlReg[0]; |
|
|
// generate status register clearable bits |
reg dirq, int; |
|
always@(posedge wb_clk_i or negedge rst_nreset_i) |
if (~rst_nreset_i) |
begin |
int <= 1'b0; |
dirq <= 1'b0; |
end |
else if (wb_rst_i) |
begin |
int <= 1'b0; |
dirq <= 1'b0; |
end |
else |
begin |
int <= (int | (irq & !dirq)) & !(sel_stat & !wb_dat_i[0]); |
dirq <= irq; |
end |
|
// assign status bits |
assign stat[31:28] = DeviceId; // set Device ID |
assign stat[27:24] = RevisionNo; // set revision number |
assign stat[23: 1] = 0; // --clear unused bits-- |
// Although stat[7]=PIOtip this bit is zero, because it is impossible |
// to read the status register and access the PIO registers at the same time. |
assign stat[0] = int; |
|
|
// generate PIO compatible / command-port timing register |
always@(posedge wb_clk_i or negedge rst_nreset_i) |
if (~rst_nreset_i) |
begin |
PIO_cmdport_T1 <= PIO_mode0_T1; |
PIO_cmdport_T2 <= PIO_mode0_T2; |
PIO_cmdport_T4 <= PIO_mode0_T4; |
PIO_cmdport_Teoc <= PIO_mode0_Teoc; |
end |
else if (wb_rst_i) |
begin |
PIO_cmdport_T1 <= PIO_mode0_T1; |
PIO_cmdport_T2 <= PIO_mode0_T2; |
PIO_cmdport_T4 <= PIO_mode0_T4; |
PIO_cmdport_Teoc <= PIO_mode0_Teoc; |
end |
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 |
// |
atahost_controller #(TWIDTH, PIO_mode0_T1, PIO_mode0_T2, PIO_mode0_T4, PIO_mode0_Teoc) |
u1 ( |
.clk(wb_clk_i), |
.nReset(rst_nreset_i), |
.rst(wb_rst_i), |
.irq(irq), |
.IDEctrl_rst(IDEctrl_rst), |
.IDEctrl_IDEen(IDEctrl_IDEen), |
.PIO_cmdport_T1(PIO_cmdport_T1), |
.PIO_cmdport_T2(PIO_cmdport_T2), |
.PIO_cmdport_T4(PIO_cmdport_T4), |
.PIO_cmdport_Teoc(PIO_cmdport_Teoc), |
.PIO_cmdport_IORDYen(PIO_cmdport_IORDYen), |
.PIOreq(PIOsel), |
.PIOack(PIOack), |
.PIOa(wb_adr_i[5:2]), |
.PIOd(wb_dat_i[15:0]), |
.PIOq(PIOq), |
.PIOwe(wb_we_i), |
.RESETn(ata_resetn_pad_o), |
.DDi(ata_dd_pad_i), |
.DDo(ata_dd_pad_o), |
.DDoe(ata_dd_pad_oe), |
.DA(ata_da_pad_o), |
.CS0n(ata_cs0n_pad_o), |
.CS1n(ata_cs1n_pad_o), |
.DIORn(ata_diorn_pad_o), |
.DIOWn(ata_diown_pad_o), |
.IORDY(ata_iordy_pad_i), |
.INTRQ(ata_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 |
/trunk/rtl/verilog/ocidec-1/atahost_controller.v
0,0 → 1,193
// |
// file: controller.v |
// description: OCIDEC1 OpenCores IDE controller type-1 |
// author : Richard Herveille |
// rev.: 1.0 june 28th, 2001. Initial Verilog release |
// rev.: 1.1 July 3rd, 2001. Rewrote "IORDY" and "INTRQ" capture section. |
// rev.: 1.2 July 9th, 2001. Added "timescale". Undid "IORDY & INTRQ" rewrite. |
// rev.: 1.3 July 11th, 2001. Changed PIOreq & PIOack generation (made them synchronous). |
// rev.: 1.4 July 26th, 2001. Fixed non-blocking assignments. |
|
// OCIDEC1 supports: |
// -Common Compatible timing access to all connected devices |
// |
|
`include "timescale.v" |
|
module atahost_controller (clk, nReset, rst, irq, IDEctrl_rst, IDEctrl_IDEen, |
PIO_cmdport_T1, PIO_cmdport_T2, PIO_cmdport_T4, PIO_cmdport_Teoc, PIO_cmdport_IORDYen, |
PIOreq, PIOack, PIOa, PIOd, PIOq, PIOwe, |
RESETn, DDi, DDo, DDoe, DA, CS0n, CS1n, DIORn, DIOWn, IORDY, INTRQ); |
// |
// parameter declarations |
// |
parameter TWIDTH = 8; // counter width |
// PIO mode 0 timing settings @100MHz master clock |
parameter PIO_mode0_T1 = 6; // 70ns |
parameter PIO_mode0_T2 = 28; // 290ns |
parameter PIO_mode0_T4 = 2; // 30ns |
parameter PIO_mode0_Teoc = 23; // 240ns ==> T0 - T1 - T2 = 600 - 70 - 290 = 240 |
// |
// inputs & outputs |
// |
input clk; //master clock |
input nReset; // asynchronous active low reset |
input rst; // synchronous active high reset |
|
output irq; // interrupt request signal |
reg irq; |
|
// control bits |
input IDEctrl_rst; |
input IDEctrl_IDEen; |
|
// PIO timing registers |
input [7:0] PIO_cmdport_T1; |
input [7:0] PIO_cmdport_T2; |
input [7:0] PIO_cmdport_T4; |
input [7:0] PIO_cmdport_Teoc; |
input PIO_cmdport_IORDYen; |
|
// PIO control signals |
input PIOreq; // PIO transfer request |
output PIOack; // PIO transfer ended |
input [ 3:0] PIOa; // PIO address |
input [15:0] PIOd; // PIO data in |
output [15:0] PIOq; // PIO data out |
input PIOwe; // PIO direction bit. 1'b1==write, 1'b0==read |
|
reg [15:0] PIOq; |
reg PIOack; |
|
// ATA signals |
output RESETn; |
input [15:0] DDi; |
output [15:0] DDo; |
output DDoe; |
output [ 2:0] DA; |
output CS0n; |
output CS1n; |
output DIORn; |
output DIOWn; |
input IORDY; |
input INTRQ; |
|
reg RESETn; |
reg [15:0] DDo; |
reg DDoe; |
reg [ 2:0] DA; |
reg CS0n; |
reg CS1n; |
reg DIORn; |
reg DIOWn; |
|
// |
// Variable declarations |
// |
|
reg dPIOreq; |
reg PIOgo; // start PIO timing controller |
wire PIOdone; // PIO timing controller done |
|
// PIO signals |
wire PIOdior, PIOdiow; |
wire PIOoe; |
|
// Timing settings |
wire dstrb; |
wire [TWIDTH-1:0] T1, T2, T4, Teoc; |
wire IORDYen; |
|
// synchronized ATA inputs |
reg sIORDY; |
|
// |
// Module body |
// |
|
|
// synchronize incoming signals |
reg cIORDY; // capture IORDY |
reg cINTRQ; // capture INTRQ |
|
always@(posedge clk) |
begin : synch_incoming |
|
cIORDY <= IORDY; |
cINTRQ <= INTRQ; |
|
sIORDY <= cIORDY; |
irq <= cINTRQ; |
end |
|
// generate ATA signals |
always@(posedge clk or negedge nReset) |
if (~nReset) |
begin |
RESETn <= 1'b0; |
DIORn <= 1'b1; |
DIOWn <= 1'b1; |
DA <= 0; // ???? |
CS0n <= 1'b1; |
CS1n <= 1'b1; |
DDo <= 0; |
DDoe <= 1'b0; |
end |
else if (rst) |
begin |
RESETn <= 1'b0; |
DIORn <= 1'b1; |
DIOWn <= 1'b1; |
DA <= 0; // ???? |
CS0n <= 1'b1; |
CS1n <= 1'b1; |
DDo <= 0; |
DDoe <= 1'b0; |
end |
else |
begin |
RESETn <= !IDEctrl_rst; |
DA <= PIOa[2:0]; |
CS0n <= !( !PIOa[3] & PIOreq); // CS0 asserted when A(3) = '0' |
CS1n <= !( PIOa[3] & PIOreq); // CS1 asserted when A(3) = '1' |
|
DDo <= PIOd; |
DDoe <= PIOoe; |
DIORn <= !PIOdior; |
DIOWn <= !PIOdiow; |
end |
|
|
// |
////////////////////////// |
// PIO transfer control // |
////////////////////////// |
// |
// capture ATA data for PIO access |
always@(posedge clk) |
if (dstrb) |
PIOq <= DDi; |
|
// generate PIOgo signal |
always@(posedge clk) |
begin |
dPIOreq <= PIOreq & !PIOack; |
PIOgo <= (PIOreq & !dPIOreq) & IDEctrl_IDEen; |
end |
|
// set Timing signals |
assign T1 = PIO_cmdport_T1; |
assign T2 = PIO_cmdport_T2; |
assign T4 = PIO_cmdport_T4; |
assign Teoc = PIO_cmdport_Teoc; |
assign IORDYen = PIO_cmdport_IORDYen; |
|
// hookup timing controller |
atahost_pio_tctrl #(TWIDTH, PIO_mode0_T1, PIO_mode0_T2, PIO_mode0_T4, PIO_mode0_Teoc) |
PIO_timing_controller (.clk(clk), .nReset(nReset), .rst(rst), .IORDY_en(IORDYen), .T1(T1), .T2(T2), .T4(T4), .Teoc(Teoc), |
.go(PIOgo), .we(PIOwe), .oe(PIOoe), .done(PIOdone), .dstrb(dstrb), .DIOR(PIOdior), .DIOW(PIOdiow), .IORDY(sIORDY) ); |
|
always@(posedge clk) |
PIOack <= PIOdone | (PIOreq & !IDEctrl_IDEen); // acknowledge when done or when IDE not enabled (discard request) |
|
endmodule |
/trunk/rtl/verilog/ocidec-1/timescale.v
0,0 → 1,2
`timescale 1ns / 10ps |
|
/trunk/rtl/verilog/ocidec-1/revision_history.txt
45,3 → 45,11
Author: Richard Herveille |
- Fixed some blocking versus non-blocking statement issues. |
----------------------------- |
|
----------------------------- |
Revision: 1.5 |
Date: August 15th, 2001. |
Author: Richard Herveille |
- Changed filenames and top-level port names to be conform new OpenCores conventions |
----------------------------- |
|