diff --git a/Archie.sv b/Archie.sv index 10984d9..82fc870 100644 --- a/Archie.sv +++ b/Archie.sv @@ -180,7 +180,7 @@ assign {DDRAM_CLK, DDRAM_BURSTCNT, DDRAM_ADDR, DDRAM_DIN, DDRAM_BE, DDRAM_RD, DD assign {SD_SCK, SD_MOSI, SD_CS} = 'Z; assign LED_USER = fdd_led; -assign LED_DISK = 0; +assign LED_DISK = hdd_led; assign LED_POWER = 0; assign BUTTONS = 0; assign HDMI_FREEZE = 0; @@ -305,15 +305,12 @@ hps_ext hps_ext .cmos_cnt ( cmos_cnt ), - .ide_reset ( reset ), .ide_req ( ide_req ), - .ide_ack ( ide_ack ), - .ide_err ( ide_err ), - .ide_adr ( ide_adr ), - .ide_dat_o ( ide_dat_i ), - .ide_dat_i ( ide_dat_o ), - .ide_rd ( ide_rd ), - .ide_we ( ide_we ) + .ide_addr ( ide_address ), + .ide_wr ( ide_write ), + .ide_dout ( ide_writedata ), + .ide_rd ( ide_read ), + .ide_din ( ide_readdata ) ); assign AUDIO_S = 1; @@ -337,16 +334,15 @@ wire [1:0] selpix; wire i2c_din, i2c_dout, i2c_clock; -wire ide_req; -wire ide_ack; -wire ide_err; -wire [8:0] ide_adr; -wire [15:0] ide_dat_o; -wire [15:0] ide_dat_i; -wire ide_rd; -wire ide_we; +wire [5:0] ide_req; +wire [4:0] ide_address; +wire ide_write; +wire [15:0] ide_writedata; +wire ide_read; +wire [15:0] ide_readdata; wire fdd_led; +wire hdd_led; archimedes_top #(CLKSYS) ARCHIMEDES ( @@ -384,7 +380,8 @@ archimedes_top #(CLKSYS) ARCHIMEDES .I2C_DIN ( i2c_dout ), .I2C_CLOCK ( i2c_clock ), - .FDD_LED ( fdd_led ), + .fdd_led ( fdd_led ), + .hdd_led ( hdd_led ), .sd_lba ( sd_lba ), .sd_rd ( sd_rd ), @@ -399,13 +396,11 @@ archimedes_top #(CLKSYS) ARCHIMEDES .img_wp ( img_readonly ), .ide_req ( ide_req ), - .ide_ack ( ide_ack ), - .ide_err ( ide_err ), - .ide_adr ( ide_adr ), - .ide_dat_o ( ide_dat_o ), - .ide_dat_i ( ide_dat_i ), - .ide_rd ( ide_rd ), - .ide_we ( ide_we ), + .ide_address ( ide_address ), + .ide_write ( ide_write ), + .ide_writedata ( ide_writedata ), + .ide_read ( ide_read ), + .ide_readdata ( ide_readdata ), .KBD_OUT_DATA ( kbd_out_data ), .KBD_OUT_STROBE ( kbd_out_strobe ), diff --git a/files.qip b/files.qip index b65adaf..141081a 100644 --- a/files.qip +++ b/files.qip @@ -4,7 +4,8 @@ set_global_assignment -name QIP_FILE rtl/fdc/fdc.qip set_global_assignment -name VERILOG_FILE rtl/sdram.v set_global_assignment -name VHDL_FILE rtl/bram.vhd set_global_assignment -name SYSTEMVERILOG_FILE rtl/EEPROM_24C0x.sv -set_global_assignment -name SYSTEMVERILOG_FILE rtl/ide.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/podule_ide.sv +set_global_assignment -name VERILOG_FILE rtl/ide.v set_global_assignment -name VERILOG_FILE rtl/latches.v set_global_assignment -name VERILOG_FILE rtl/ioc_irq.v set_global_assignment -name VERILOG_FILE rtl/ioc.v diff --git a/rtl/archimedes_top.v b/rtl/archimedes_top.v index b3f761f..5c7fa9b 100644 --- a/rtl/archimedes_top.v +++ b/rtl/archimedes_top.v @@ -27,48 +27,48 @@ module archimedes_top #(parameter CLKCPU) input CLKPIX_I, input CEPIX_I, output [1:0] SELPIX_O, - + input CEAUD_I, - input RESET_I, - + input RESET_I, + // cpu wishbone interface. output MEM_CYC_O, output MEM_STB_O, output MEM_WE_O, - + input MEM_ACK_I, input MEM_ERR_I, input MEM_RTY_I, - + output [3:0] MEM_SEL_O, output [2:0] MEM_CTI_O, output [23:2] MEM_ADDR_O, - - input [31:0] MEM_DAT_I, + + input [31:0] MEM_DAT_I, output [31:0] MEM_DAT_O, // video signals (VGA) output HSYNC, output VSYNC, - + output [3:0] VIDEO_R, output [3:0] VIDEO_G, output [3:0] VIDEO_B, output VIDEO_EN, - + // VIDC Enhancer selection. // These are from external latch C output [1:0] VIDBASECLK_O, output [1:0] VIDSYNCPOL_O, - - // I2C bus to the CMOS. - output I2C_DOUT, - input I2C_DIN, - output I2C_CLOCK, - // "Floppy" LED - output FDD_LED, + // I2C bus to the CMOS. + output I2C_DOUT, + input I2C_DIN, + output I2C_CLOCK, + + output fdd_led, + output hdd_led, // floppy connections to external controller input [1:0] img_mounted, // signaling that new image has been mounted @@ -84,85 +84,83 @@ module archimedes_top #(parameter CLKCPU) input sd_buff_wr, // connection to the IDE controller - output ide_req, // new command request - input ide_err, - input ide_ack, // command finished on the IO controller side - input [8:0] ide_adr, - output [15:0] ide_dat_o, - input [15:0] ide_dat_i, - input ide_rd, - input ide_we, + output [5:0] ide_req, + input [4:0] ide_address, + input ide_write, + input [15:0] ide_writedata, + input ide_read, + output [15:0] ide_readdata, // connection to keyboard controller output [7:0] KBD_OUT_DATA, output KBD_OUT_STROBE, input [7:0] KBD_IN_DATA, input KBD_IN_STROBE, - + input [4:0] JOYSTICK0, input [4:0] JOYSTICK1, - + // audio signal. output [15:0] AUDIO_L, output [15:0] AUDIO_R - -); + +); // cpu bus wire [31:0] cpu_address; -wire [3:0] cpu_sel; +wire [3:0] cpu_sel; -wire cpu_spvmd; +wire cpu_spvmd; wire [31:0] cpu_dat_o; wire [31:0] cpu_dat_i; -wire cpu_cyc; -wire cpu_stb; -wire cpu_we; +wire cpu_cyc; +wire cpu_stb; +wire cpu_we; -wire cpu_ack; -wire cpu_err; -wire cpu_irq; -wire cpu_firq; +wire cpu_ack; +wire cpu_err; +wire cpu_irq; +wire cpu_firq; // video DMA signals. -wire [31:0] vid_address; // VIDC D31-D0 -wire vid_flybk; // VIDC FLYBK -wire vid_req; // VIDC REQ -wire vid_ack; // VIDC ACK +wire [31:0] vid_address; // VIDC D31-D0 +wire vid_flybk; // VIDC FLYBK +wire vid_req; // VIDC REQ +wire vid_ack; // VIDC ACK -wire ioc_cs; -wire ioc_ack; -wire [7:0] ioc_dat_o; +wire ioc_cs; +wire ioc_ack; +wire [7:0] ioc_dat_o; -wire rom_low_cs; -wire [5:0] ioc_cin, ioc_cout; +wire rom_low_cs; +wire [5:0] ioc_cin, ioc_cout; a23_core ARM( - .i_clk ( CLKCPU_I ), - .i_reset ( RESET_I ), - - .o_wb_cyc ( cpu_cyc ), - .o_wb_stb ( cpu_stb ), - .o_wb_we ( cpu_we ), + .i_clk ( CLKCPU_I ), + .i_reset ( RESET_I ), - .o_wb_adr ( cpu_address ), - .o_wb_sel ( cpu_sel ), + .o_wb_cyc ( cpu_cyc ), + .o_wb_stb ( cpu_stb ), + .o_wb_we ( cpu_we ), - .i_wb_dat ( cpu_dat_i ), - .o_wb_dat ( cpu_dat_o ), - + .o_wb_adr ( cpu_address ), + .o_wb_sel ( cpu_sel ), - .i_wb_ack ( cpu_ack ), - .i_wb_err ( cpu_err ), - - .o_wb_tga ( cpu_spvmd ), - .i_irq ( cpu_irq ), - .i_firq ( cpu_firq ), - - .i_system_rdy(~RESET_I ) + .i_wb_dat ( cpu_dat_i ), + .o_wb_dat ( cpu_dat_o ), + + + .i_wb_ack ( cpu_ack ), + .i_wb_err ( cpu_err ), + + .o_wb_tga ( cpu_spvmd ), + .i_irq ( cpu_irq ), + .i_firq ( cpu_firq ), + + .i_system_rdy(~RESET_I ) ); wire sirq_n; @@ -172,49 +170,49 @@ wire snd_ack, snd_req; wire [31:0] cpu_dout; memc MEMC( - - .clkcpu ( CLKCPU_I ), - .rst_i ( RESET_I ), - - .spvmd ( cpu_spvmd ), + + .clkcpu ( CLKCPU_I ), + .rst_i ( RESET_I ), + + .spvmd ( cpu_spvmd ), // cpu interface - .cpu_address ( cpu_address[25:0] ), - .cpu_cyc ( cpu_cyc ), - .cpu_stb ( cpu_stb ), - .cpu_we ( cpu_we ), - .cpu_sel ( cpu_sel ), - .cpu_ack ( cpu_ack ), - .cpu_err ( cpu_err ), - .cpu_dout ( cpu_dout ), - + .cpu_address ( cpu_address[25:0] ), + .cpu_cyc ( cpu_cyc ), + .cpu_stb ( cpu_stb ), + .cpu_we ( cpu_we ), + .cpu_sel ( cpu_sel ), + .cpu_ack ( cpu_ack ), + .cpu_err ( cpu_err ), + .cpu_dout ( cpu_dout ), + // memory interface - .mem_addr_o ( MEM_ADDR_O ), - .mem_stb_o ( MEM_STB_O ), - .mem_cyc_o ( MEM_CYC_O ), - .mem_ack_i ( MEM_ACK_I ), - .mem_sel_o ( MEM_SEL_O ), - .mem_we_o ( MEM_WE_O ), - .mem_cti_o ( MEM_CTI_O ), + .mem_addr_o ( MEM_ADDR_O ), + .mem_stb_o ( MEM_STB_O ), + .mem_cyc_o ( MEM_CYC_O ), + .mem_ack_i ( MEM_ACK_I ), + .mem_sel_o ( MEM_SEL_O ), + .mem_we_o ( MEM_WE_O ), + .mem_cti_o ( MEM_CTI_O ), .mem_dat_i ( MEM_DAT_I ), - + // vidc interface - .hsync ( HSYNC ), - .flybk ( vid_flybk ), - .vidrq ( vid_req ), - .vidak ( vid_ack ), - .sndak ( snd_ack ), - .sndrq ( snd_req ), - .vidw ( vid_we ), - + .hsync ( HSYNC ), + .flybk ( vid_flybk ), + .vidrq ( vid_req ), + .vidak ( vid_ack ), + .sndak ( snd_ack ), + .sndrq ( snd_req ), + .vidw ( vid_we ), + // ioc interface - .ioc_cs ( ioc_cs ), - .rom_low_cs ( rom_low_cs ), - .ram_cs ( ram_cs ), - + .ioc_cs ( ioc_cs ), + .rom_low_cs ( rom_low_cs ), + .ram_cs ( ram_cs ), + // irqs - - .sirq_n ( sirq_n ) + + .sirq_n ( sirq_n ) ); vidc #(CLKCPU) VIDC @@ -225,12 +223,12 @@ vidc #(CLKCPU) VIDC .ceaud ( CEAUD_I ), - .clkcpu ( CLKCPU_I ), + .clkcpu ( CLKCPU_I ), .rst_i ( RESET_I ), .cpu_dat ( cpu_dat_o ), - // memc + // memc .flybk ( vid_flybk ), .vidak ( vid_ack ), .vidrq ( vid_req ), @@ -243,9 +241,9 @@ vidc #(CLKCPU) VIDC // video signals .hsync ( HSYNC ), .vsync ( VSYNC ), - .video_r ( VIDEO_R ), - .video_g ( VIDEO_G ), - .video_b ( VIDEO_B ), + .video_r ( VIDEO_R ), + .video_g ( VIDEO_G ), + .video_b ( VIDEO_B ), .video_en ( VIDEO_EN ), // audio signals @@ -253,12 +251,12 @@ vidc #(CLKCPU) VIDC .audio_r ( AUDIO_R ) ); -wire [1:0] ioc_speed = cpu_address[20:19]; -wire [7:1] ioc_select; -wire ioc_sext; +wire [1:0] ioc_speed = cpu_address[20:19]; +wire [7:1] ioc_select; +wire ioc_sext; // podule data bus. -wire [15:0] pod_dat_o; -wire [15:0] pod_dat_i; +wire [15:0] pod_dat_o; +wire [15:0] pod_dat_i; wire floppy_firq; wire floppy_drq; @@ -267,40 +265,40 @@ wire ioc_clk2m_en, ioc_clk8m_en; ioc IOC( - .clkcpu ( CLKCPU_I ), - .clk2m_en ( ioc_clk2m_en ), - .clk8m_en ( ioc_clk8m_en ), - - .por ( RESET_I ), - .ir ( vid_flybk ), - - .fh ( {floppy_firq, floppy_drq}), - - .il ( {6'b1111, sirq_n, 1'b1 }), - - .c_in ( ioc_cin ), - .c_out ( ioc_cout ), - - .select ( ioc_select ), - .sext ( ioc_sext ), - - // wishbone bus - .wb_adr ( cpu_address[6:2] ), - .wb_stb ( cpu_stb & cpu_address[21] & ioc_cs ), - .wb_cyc ( cpu_cyc & cpu_address[21] & ioc_cs ), - .wb_we ( cpu_we ), + .clkcpu ( CLKCPU_I ), + .clk2m_en ( ioc_clk2m_en ), + .clk8m_en ( ioc_clk8m_en ), - .wb_dat_i ( cpu_dat_o[23:16] ), - .wb_dat_o ( ioc_dat_o ), - .wb_bank ( cpu_address[18:16] ), - - .irq ( cpu_irq ), - .firq ( cpu_firq ), - - .kbd_out_data ( KBD_OUT_DATA ), - .kbd_out_strobe( KBD_OUT_STROBE ), - .kbd_in_data ( KBD_IN_DATA ), - .kbd_in_strobe ( KBD_IN_STROBE ) + .por ( RESET_I ), + .ir ( vid_flybk ), + + .fh ( {floppy_firq, floppy_drq}), + + .il ( {6'b1111, sirq_n, 1'b1 }), + + .c_in ( ioc_cin ), + .c_out ( ioc_cout ), + + .select ( ioc_select ), + .sext ( ioc_sext ), + + // wishbone bus + .wb_adr ( cpu_address[6:2] ), + .wb_stb ( cpu_stb & cpu_address[21] & ioc_cs ), + .wb_cyc ( cpu_cyc & cpu_address[21] & ioc_cs ), + .wb_we ( cpu_we ), + + .wb_dat_i ( cpu_dat_o[23:16] ), + .wb_dat_o ( ioc_dat_o ), + .wb_bank ( cpu_address[18:16] ), + + .irq ( cpu_irq ), + .firq ( cpu_firq ), + + .kbd_out_data ( KBD_OUT_DATA ), + .kbd_out_strobe( KBD_OUT_STROBE ), + .kbd_in_data ( KBD_IN_DATA ), + .kbd_in_strobe ( KBD_IN_STROBE ) ); localparam PODULE0 = 2'b00; @@ -321,7 +319,7 @@ wire [15:0] podule3_rdata; reg [15:0] podule_rdata; always @(*) begin podule_rdata = 16'hFFFF; - + if(podule_num == PODULE0) podule_rdata = podule0_rdata; //if(podule_num == PODULE1) podule_rdata = podule1_rdata; //if(podule_num == PODULE2) podule_rdata = podule2_rdata; @@ -334,16 +332,16 @@ wire podule0_sel = podules_en && cpu_stb && cpu_cyc && podule_num == PODULE0; //wire podule3_sel = podules_en && cpu_stb && cpu_cyc && podule_num == PODULE3; -wire [7:0] floppy_dat_o; -wire floppy_en = ioc_cs & ioc_select[1]; +wire [7:0] floppy_dat_o; +wire floppy_en = ioc_cs & ioc_select[1]; // floppy drive signals. wire [3:0] floppy_drive; -wire floppy_side; -wire floppy_motor; -wire floppy_inuse; -wire floppy_density; -wire floppy_reset; +wire floppy_side; +wire floppy_motor; +wire floppy_inuse; +wire floppy_density; +wire floppy_reset; wire fdc_sel = cpu_stb & cpu_cyc & floppy_en; fdc1772 #(CLKCPU) FDC1772 ( @@ -371,16 +369,16 @@ fdc1772 #(CLKCPU) FDC1772 ( .sd_din ( sd_buff_din ), .sd_dout_strobe ( sd_buff_wr ), - .floppy_drive ( floppy_drive ), -// .floppy_motor ( floppy_motor ), -// .floppy_inuse ( floppy_inuse ), - .floppy_side ( floppy_side ), -// .floppy_density ( floppy_density ), - .floppy_reset ( floppy_reset ) + .floppy_drive ( floppy_drive ), +// .floppy_motor ( floppy_motor ), +// .floppy_inuse ( floppy_inuse ), + .floppy_side ( floppy_side ), +// .floppy_density ( floppy_density ), + .floppy_reset ( floppy_reset ) ); -ide IDE ( +podule_ide IDE ( .clk ( CLKCPU_I ), .reset ( RESET_I ), @@ -390,60 +388,59 @@ ide IDE ( .cpu_dat_o ( podule0_rdata ), .cpu_dat_i ( podule_wdata ), - .ide_req ( ide_req ), - .ide_ack ( ide_ack ), - .ide_err ( ide_err ), + .hdd_led ( hdd_led ), - .ide_adr ( ide_adr ), - .ide_dat_o ( ide_dat_o ), - .ide_dat_i ( ide_dat_i ), - .ide_we ( ide_we ), - .ide_rd ( ide_rd ) + .ide_req ( ide_req ), + .ide_address ( ide_address ), + .ide_write ( ide_write ), + .ide_writedata ( ide_writedata ), + .ide_read ( ide_read ), + .ide_readdata ( ide_readdata ) ); -wire [7:0] latches_dat_o; -wire latches_en = ioc_cs & ioc_select[5] & (ioc_speed == 2'd2); +wire [7:0] latches_dat_o; +wire latches_en = ioc_cs & ioc_select[5] & (ioc_speed == 2'd2); latches LATCHES( - .clkcpu ( CLKCPU_I ), + .clkcpu ( CLKCPU_I ), - .wb_cyc ( cpu_cyc & latches_en ), - .wb_stb ( cpu_stb & latches_en ), - .wb_we ( cpu_we & latches_en ), + .wb_cyc ( cpu_cyc & latches_en ), + .wb_stb ( cpu_stb & latches_en ), + .wb_we ( cpu_we & latches_en ), - .wb_dat_i ( cpu_dat_o[23:16] ), - .wb_dat_o ( latches_dat_o ), - .wb_adr ( cpu_address[15:2] ), - - .floppy_drive ( floppy_drive ), - .floppy_motor ( floppy_motor ), - .floppy_inuse ( floppy_inuse ), - .floppy_side ( floppy_side ), - .floppy_density( floppy_density ), - .floppy_reset ( floppy_reset ), - - .joy0 ( JOYSTICK0 ), - .joy1 ( JOYSTICK1 ), - - .baseclk ( VIDBASECLK_O ), - .syncpol ( VIDSYNCPOL_O ) + .wb_dat_i ( cpu_dat_o[23:16] ), + .wb_dat_o ( latches_dat_o ), + .wb_adr ( cpu_address[15:2] ), + + .floppy_drive ( floppy_drive ), + .floppy_motor ( floppy_motor ), + .floppy_inuse ( floppy_inuse ), + .floppy_side ( floppy_side ), + .floppy_density( floppy_density ), + .floppy_reset ( floppy_reset ), + + .joy0 ( JOYSTICK0 ), + .joy1 ( JOYSTICK1 ), + + .baseclk ( VIDBASECLK_O ), + .syncpol ( VIDSYNCPOL_O ) ); -assign MEM_DAT_O = cpu_dat_o; +assign MEM_DAT_O = cpu_dat_o; -assign cpu_dat_i = floppy_en ? {24'd0, floppy_dat_o} : - latches_en ? {24'd0, latches_dat_o} : - podules_en ? {16'd0, podule_rdata} : - ioc_cs & ~ioc_sext ? {24'd0, ioc_dat_o} : - ram_cs ? cpu_dout : +assign cpu_dat_i = floppy_en ? {24'd0, floppy_dat_o} : + latches_en ? {24'd0, latches_dat_o} : + podules_en ? {16'd0, podule_rdata} : + ioc_cs & ~ioc_sext ? {24'd0, ioc_dat_o} : + ram_cs ? cpu_dout : 32'hFFFF_FFFF; - -assign I2C_CLOCK = ioc_cout[1]; -assign I2C_DOUT = ioc_cout[0]; - -assign ioc_cin[5:0] = {ioc_cout[5:2], I2C_CLOCK, I2C_DIN}; -assign FDD_LED = ~floppy_inuse; + +assign I2C_CLOCK = ioc_cout[1]; +assign I2C_DOUT = ioc_cout[0]; + +assign ioc_cin[5:0] = {ioc_cout[5:2], I2C_CLOCK, I2C_DIN}; +assign fdd_led = ~floppy_inuse; endmodule // archimedes_top diff --git a/rtl/hps_ext.v b/rtl/hps_ext.v index c50faa3..0705748 100644 --- a/rtl/hps_ext.v +++ b/rtl/hps_ext.v @@ -30,41 +30,44 @@ module hps_ext input [7:0] cmos_cnt, - input ide_reset, - input ide_req, - output reg ide_ack, - output reg ide_err, - output reg [8:0] ide_adr, - output reg [15:0] ide_dat_o, - input [15:0] ide_dat_i, + input [15:0] ide_din, + output reg [15:0] ide_dout, + output reg [4:0] ide_addr, output reg ide_rd, - output reg ide_we + output reg ide_wr, + input [5:0] ide_req ); -assign EXT_BUS[15:0] = fp_dout_en ? fp_dout : io_dout; +assign EXT_BUS[15:0] = io_dout; wire [15:0] io_din = EXT_BUS[31:16]; -assign EXT_BUS[32] = io_dout_en | fp_dout_en; +assign EXT_BUS[32] = io_dout_en; wire io_strobe = EXT_BUS[33]; wire io_enable = EXT_BUS[34]; -wire fp_enable = EXT_BUS[35]; localparam EXT_CMD_MIN = 4; localparam EXT_CMD_MAX = 5; +localparam EXT_CMD_MIN2= 'h61; +localparam EXT_CMD_MAX2= 'h63; reg [15:0] io_dout; reg io_dout_en; always@(posedge clk_sys) begin reg [7:0] cmd; + reg ide_cs = 0; reg [3:0] byte_cnt; reg old_out_strobe = 0; reg kbd_out_data_available = 0; + {ide_rd, ide_wr} <= 0; + if((ide_rd | ide_wr) & ~&ide_addr[3:0]) ide_addr <= ide_addr + 1'd1; + kbd_in_strobe <= 0; old_out_strobe <= kbd_out_strobe; if(~old_out_strobe && kbd_out_strobe) kbd_out_data_available <= 1; if(~io_enable) begin byte_cnt <= 0; + ide_cs <= 0; io_dout <= 0; io_dout_en <= 0; end else begin @@ -72,10 +75,16 @@ always@(posedge clk_sys) begin io_dout <= 0; if(~&byte_cnt) byte_cnt <= byte_cnt + 1'd1; + ide_dout <= io_din; + if(byte_cnt == 1) begin + ide_addr <= {io_din[8],io_din[3:0]}; + ide_cs <= (io_din[15:9] == 7'b1111000); + end if(byte_cnt == 0) begin cmd <= io_din[7:0]; - io_dout_en <= (io_din >= EXT_CMD_MIN && io_din <= EXT_CMD_MAX); + io_dout_en <= (io_din >= EXT_CMD_MIN && io_din <= EXT_CMD_MAX) || (io_din >= EXT_CMD_MIN2 && io_din <= EXT_CMD_MAX2); + if(io_din == 'h63) io_dout <= {4'hE, 2'b00, 2'b00, 2'b00, ide_req}; end else begin case(cmd) @@ -91,6 +100,15 @@ always@(posedge clk_sys) begin if(byte_cnt == 1) kbd_in_strobe <= 1; kbd_in_data <= io_din[7:0]; end + + 'h61: if(byte_cnt >= 3 && ide_cs) begin + ide_wr <= 1; + end + + 'h62: if(byte_cnt >= 3 && ide_cs) begin + io_dout <= ide_din; + ide_rd <= 1; + end default: ; endcase end @@ -98,84 +116,4 @@ always@(posedge clk_sys) begin end end -localparam CMD_IDE_REGS_RD = 8'h80; -localparam CMD_IDE_REGS_WR = 8'h90; -localparam CMD_IDE_DATA_WR = 8'hA0; -localparam CMD_IDE_DATA_RD = 8'hB0; -localparam CMD_IDE_STATUS_WR = 8'hF0; - -localparam STATUS_CMD = 8'h04; -localparam STATUS_DAT = 8'h08; - -reg [15:0] fp_dout; -reg fp_dout_en; -always@(posedge clk_sys) begin - reg [7:0] cmd; - reg [1:0] byte_cnt; - reg write_start = 0; - reg newcmd = 0; - reg write_req = 0; - reg [7:0] ide_cmd; - - ide_we <= 0; - ide_rd <= 0; - ide_ack <= 0; - - if(ide_we | ide_rd) ide_adr <= ide_adr + 1'd1; - if(ide_rd && ide_adr == 9'h107) ide_cmd <= ide_dat_i[7:0]; - - if (ide_reset) begin - newcmd <= 0; - write_req <= 0; - write_start <= 0; - end - - if (ide_req) begin - ide_err <= 0; - newcmd <= 1; - write_start <= write_req; - end - - if(~ide_adr[8]) begin - if (ide_we) newcmd <= 0; - if (ide_rd) begin - write_req <= 0; - write_start <= 0; - end - end - - if(~fp_enable) begin - byte_cnt <= 0; - fp_dout <= 0; - fp_dout_en <= 0; - end - else if(io_strobe) begin - fp_dout <= 0; - if(~&byte_cnt) byte_cnt <= byte_cnt + 1'd1; - - if(!byte_cnt) begin - cmd <= io_din[15:8]; - fp_dout_en <= (io_din[15:8] >= CMD_IDE_REGS_RD && io_din[15:8] <= CMD_IDE_STATUS_WR); - if(!io_din) begin - fp_dout <= {write_start ? STATUS_DAT : newcmd ? STATUS_CMD : 8'h00, cmos_cnt}; - fp_dout_en <= 1; - end - if(io_din[15:8] == CMD_IDE_STATUS_WR) begin - if (io_din[7]) ide_ack <= 1; // IDE_STATUS_END - if (io_din[4]) newcmd <= 0; // IDE_STATUS_IRQ - if (io_din[2] || ((ide_cmd == 8'h30 || ide_cmd == 8'hc5) && io_din[4] && ~io_din[7])) write_req <= 1; - if (io_din[1]) ide_err <= 1; // IDE_STATUS_ERR - end - ide_adr <= {io_din[15:8] == CMD_IDE_REGS_RD || io_din[15:8] == CMD_IDE_REGS_WR, 8'h00}; - end - - if (&byte_cnt) begin - ide_dat_o <= io_din; - fp_dout <= ide_dat_i; - ide_we <= (cmd == CMD_IDE_REGS_WR) || (cmd == CMD_IDE_DATA_WR); - ide_rd <= (cmd == CMD_IDE_REGS_RD) || (cmd == CMD_IDE_DATA_RD); - end - end -end - endmodule diff --git a/rtl/ide.sv b/rtl/ide.sv deleted file mode 100644 index dcd7d46..0000000 --- a/rtl/ide.sv +++ /dev/null @@ -1,169 +0,0 @@ -// -// ide.sv -// -// Copyright (c) 2019 György Szombathelyi -// -// This source file is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published -// by the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This source file 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 General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// - -// altera message_off 10030 -module ide ( - input clk, // system clock. - input reset, - - input cpu_sel, - input cpu_we, - input [13:2] cpu_adr, - input [15:0] cpu_dat_i, - output [15:0] cpu_dat_o, - - // place any signals that need to be passed up to the top after here. - output ide_req, - input ide_err, - input ide_ack, - input [8:0] ide_adr, - output [15:0] ide_dat_o, - input [15:0] ide_dat_i, - input ide_we, - input ide_rd -); - -assign ide_req = ide_cmd_req | ide_sector_req; - -// RISC Developments IDE Interface in Podule 0 -reg [7:0] rd_rom[16384]; -initial $readmemh("rtl/riscdevide_rom.hex", rd_rom); - -wire reg_sel = cpu_sel && cpu_adr[13:10] == 4'hA; -wire page_sel = cpu_sel && cpu_adr[13:02] == 12'h800 && cpu_we ; - -reg [2:0] rd_page; -always @(posedge clk) begin - if (reset) rd_page <= 0; - else if (page_sel) rd_page <= cpu_dat_i[2:0]; -end - -reg [7:0] rd_rom_q; -always @(posedge clk) rd_rom_q <= rd_rom[{rd_page, cpu_adr[12:2]}]; - -wire [2:0] ide_reg = cpu_adr[4:2]; - -reg [7:0] taskfile[8]; -reg [7:0] status; - -wire ide_reg_sel = ide_adr[8]; - -// read from Task File Registers -//cpu read -wire [7:0] ide_dat_b = (ide_reg == 3'd7) ? { status[7:1], ide_err } : taskfile[ide_reg]; -assign cpu_dat_o = ~reg_sel ? {8'd0, rd_rom_q} : ((ide_reg == 3'd0) ? data_out : { ide_dat_b, ide_dat_b }); - -// IO controller read -assign ide_dat_o = ide_reg_sel ? taskfile[ide_adr[2:0]] : ide_sec_o; - -reg ide_cmd_req; -// write to Task File Registers -always @(posedge clk) begin - ide_cmd_req <= 0; - // cpu write - if (reg_sel && cpu_we) begin - taskfile[ide_reg] <= cpu_dat_i[7:0]; - // writing to the command register triggers the IO controller - if (ide_reg == 3'd7) ide_cmd_req <= 1; - end - - // IO controller write - if (ide_we & ide_reg_sel) taskfile[ide_adr[2:0]] <= ide_dat_i[7:0]; -end - -reg ide_sector_req; - -// status register handling -always @(posedge clk) begin - reg [7:0] sector_count; - - if (reset) begin - status <= 8'h48; - ide_sector_req <= 0; - sector_count <= 8'd1; - end else begin - // write to command register starts the execution - if (reg_sel && cpu_we && ide_reg == 3'd7) begin - sector_count <= taskfile[2]; - case (taskfile[7]) - 8'h30, 8'hc5: status <= 8'h08; // request data - default: status <= 8'h80; // busy - endcase - end - - if (ide_ack) begin - case (taskfile[7]) - 8'hec : status <= 8'h08; // ready to transfer - 8'h20, 8'h30, 8'hc4, 8'hc5: ; - default: status <= 8'h40; // ready - endcase - end - - // sector buffer - IO controller side - if ((ide_rd | ide_we) && ide_adr == 9'hff) status <= 8'h08; // sector buffer consumed/filled, ready to transfer - if ((ide_rd | ide_we) && ~ide_reg_sel) ide_sector_req <= 0; - - // sector buffer - CPU side - if (reg_sel_d && ~reg_sel && ide_reg == 3'd0 && data_addr == 8'hff) begin - status <= 8'h40; // ready - case (taskfile[7]) - 8'h20, 8'hc4: // reads - begin - sector_count <= sector_count - 1'd1; - if (sector_count != 1) ide_sector_req <= 1; // request the next sector - end - 8'h30, 8'hc5: - begin - ide_sector_req <= 1; // write, signals the write buffer is ready - status <= 8'h80; // busy - end - default: ; - endcase - - end - end -end - -reg [7:0] data_addr; -wire [15:0] data_out; -reg reg_sel_d; - -// read/write data register -always @(posedge clk) begin - reg_sel_d <= reg_sel; - if (reg_sel && cpu_we && ide_reg == 3'd7) data_addr <= 0; - if (reg_sel_d && ~reg_sel && ide_reg == 3'd0) data_addr <= data_addr + 1'd1; -end - -wire [15:0] ide_sec_o; -dpram #(8,16) ide_databuf ( - .clock ( clk ), - - .address_a ( data_addr ), - .data_a ( cpu_dat_i ), - .wren_a ( reg_sel && cpu_we && ide_reg == 3'd0 ), - .q_a ( data_out ), - - .address_b ( ide_adr[7:0] ), - .data_b ( ide_dat_i ), - .wren_b ( ide_we & ~ide_reg_sel ), - .q_b ( ide_sec_o ) -); - -endmodule diff --git a/rtl/ide.v b/rtl/ide.v new file mode 100644 index 0000000..3efe611 --- /dev/null +++ b/rtl/ide.v @@ -0,0 +1,314 @@ +/* + * Copyright (c) 2020, Alexey Melnikov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +module ide +( + input clk, + input rst_n, + + output reg irq, + output drq, + + input use_fast, // 1 - supports fast read mode + output no_data, // pause for system when no data is available in fast mode + + output [1:0] drive_en, + + input [3:0] io_address, + input io_read, + output reg [31:0] io_readdata, + input io_write, + input [31:0] io_writedata, + input io_32, + + output reg io_wait, + + output reg [2:0] request, + + input [3:0] mgmt_address, + input mgmt_write, + input [15:0] mgmt_writedata, + input mgmt_read, + output reg [15:0] mgmt_readdata +); + +assign drq = status[3]; +assign drive_en = present; + +//------------------------------------------------------------------------------ + +wire io_wr = io_write & |present; + +//------------------------------------------------------------------------------ + +always @(posedge clk) if(io_read) begin + if(!present) io_readdata <= 32'hFFFFFFFF; + else begin + case(io_address) + 0: io_readdata <= status[3] ? {buf_q[31:16], (~io_32 & io_cnt[0]) ? buf_q[31:16] : buf_q[15:0]} : 32'd0; + 1: io_readdata <= error; + 2: io_readdata <= (hob ? sector_count[15:8] : sector_count[7:0] ); + 3: io_readdata <= (hob ? sector[15:8] : sector[7:0] ); + 4: io_readdata <= (hob ? cylinder[23:16] : cylinder[7:0] ); + 5: io_readdata <= (hob ? cylinder[31:24] : cylinder[15:8] ); + 6: io_readdata <= drv_addr; + 7: io_readdata <= status; + 14: io_readdata <= status; + 15: io_readdata <= { 2'b10, ~drv_addr[3:0], ~drv_addr[4], drv_addr[4]}; + default: io_readdata <= 0; + endcase + end +end + +//------------------------------------------------------------------------------ + +reg [7:0] features; +always @(posedge clk) begin + if(~rst_n) features <= 8'h00; + else if(io_wr && io_address == 1) features <= io_writedata[7:0]; +end + +reg [15:0] blk_size; +always @(posedge clk) begin + if(~rst_n) blk_size <= 16'h0000; + else if(mgmt_write && mgmt_address == 0) blk_size <= {mgmt_writedata[7:0], 8'h00}; + else if(mgmt_write && mgmt_address == 4 && blk_size[15]) blk_size <= mgmt_writedata[15:0]; +end + +reg [7:0] error; +always @(posedge clk) begin + if(~rst_n) error <= 8'h00; + else if(mgmt_write && mgmt_address == 0) error <= mgmt_writedata[15:8]; +end + +reg [15:0] sector_count; +always @(posedge clk) begin + if(~rst_n) sector_count <= 16'd1; + else if(mgmt_write && mgmt_address == 1) sector_count[7:0] <= mgmt_writedata[7:0]; + else if(mgmt_write && mgmt_address == 3) sector_count[15:8] <= mgmt_writedata[7:0]; + else if(io_wr && io_address == 2) sector_count <= {sector_count[7:0], io_writedata[7:0]}; +end + +reg [15:0] sector; +always @(posedge clk) begin + if(~rst_n) sector <= 16'd1; + else if(mgmt_write && mgmt_address == 1) sector[7:0] <= mgmt_writedata[15:8]; + else if(mgmt_write && mgmt_address == 3) sector[15:8] <= mgmt_writedata[15:8]; + else if(io_wr && io_address == 3) sector <= {sector[7:0],io_writedata[7:0]}; +end + +reg [31:0] cylinder; +always @(posedge clk) begin + if(~rst_n) cylinder <= 32'hFFFFFFFF; + else if(mgmt_write && mgmt_address == 2) cylinder[15:0] <= mgmt_writedata[15:0]; + else if(mgmt_write && mgmt_address == 4) cylinder[31:16] <= mgmt_writedata[15:0]; + else if(io_wr && io_address == 4) {cylinder[23:16], cylinder[7:0] } <= {cylinder[7:0], io_writedata[7:0]}; + else if(io_wr && io_address == 5) {cylinder[31:24], cylinder[15:8]} <= {cylinder[15:8], io_writedata[7:0]}; +end + +reg [7:0] drv_addr; +always @(posedge clk) begin + if(~rst_n) drv_addr <= 8'd0; + else if(mgmt_write && mgmt_address == 5) drv_addr <= mgmt_writedata[7:0]; + else if(io_wr && io_address == 6) drv_addr <= io_writedata[7:0]; +end + +reg [7:0] cmd; +always @(posedge clk) begin + if(~rst_n) cmd <= 8'd0; + else if(io_wr && io_address == 7) cmd <= io_writedata[7:0]; +end + +reg [7:0] status = 0; +always @(posedge clk) begin + if(reset) status <= 8'h80; + else if(mgmt_write && mgmt_address == 5) status <= {mgmt_writedata[15:14],1'b0,mgmt_writedata[12:11],2'b00,mgmt_writedata[8]}; + else if(io_wr && io_address == 7) status <= 8'h80; + else if(io_done & drq & last_read) status <= 8'h40; + else if(io_done & drq) status <= 8'h80; +end + +reg last_read = 0; +always @(posedge clk) begin + if(reset) last_read <= 0; + else if(mgmt_write && mgmt_address == 5) last_read <= mgmt_writedata[9]; + else if(io_done & drq) last_read <= 0; +end + +reg fast_read = 0; +always @(posedge clk) begin + if(reset) fast_read <= 0; + else if(mgmt_write && mgmt_address == 5) fast_read <= mgmt_writedata[13]; + else if(io_done & drq) fast_read <= 0; +end + +always @(posedge clk) begin + if(~rst_n) io_wait <= 1'd0; + else if(sw_reset) io_wait <= use_wait; + else if(mgmt_write && mgmt_address == 5) io_wait <= 1'd0; + else if(io_wr && io_address == 7) io_wait <= use_wait; + else if(io_done & drq) io_wait <= use_wait; +end + +always @(posedge clk) begin + if(reset) request <= 3'b110; // reset + else if(mgmt_write && mgmt_address == 5) request <= 3'b000; + else if(io_wr && io_address == 7) request <= 3'b100; // new command + else if(io_done & drq & ~last_read) request <= 3'b101; // data send/recv +end + +always @(posedge clk) begin + if(reset) irq <= 1'b0; + else if(mgmt_write && mgmt_address == 5 && mgmt_writedata[10] && ~disable_irq) irq <= 1'b1; + else if((io_read | io_wr) && io_address == 7) irq <= 1'b0; +end + +always @(posedge clk) begin + case(mgmt_address) + 0: mgmt_readdata <= {features, 6'd0, use_fast, io_done}; + 1: mgmt_readdata <= {sector[7:0], sector_count[7:0]}; + 2: mgmt_readdata <= {cylinder[15:0]}; + 3: mgmt_readdata <= {sector[15:8], sector_count[15:8]}; + 4: mgmt_readdata <= {cylinder[31:16]}; + 5: mgmt_readdata <= {cmd, drv_addr}; + default: mgmt_readdata <= (mgmt_cnt[0]) ? buf_readdata[31:16] : buf_readdata[15:0]; + endcase +end + +//------------------------------------------------------------------------------ + +reg [1:0] hob_ena = 0; +reg [1:0] present = 0; +always @(posedge clk) begin + if(mgmt_write && mgmt_address == 6 && mgmt_writedata[3]) {hob_ena[0], present[0]} <= mgmt_writedata[1:0]; + if(mgmt_write && mgmt_address == 6 && mgmt_writedata[7]) {hob_ena[1], present[1]} <= mgmt_writedata[5:4]; +end + +reg use_wait = 0; +always @(posedge clk) begin + if(mgmt_write && mgmt_address == 6 && mgmt_writedata[9]) use_wait <= mgmt_writedata[8]; +end + +//------------------------------------------------------------------------------ + +wire reset = ~rst_n | sw_reset; + +reg disable_irq; +always @(posedge clk) begin + if(reset) disable_irq <= 1'b0; + else if(io_wr && io_address == 14) disable_irq <= io_writedata[1]; +end + +reg sw_reset; +always @(posedge clk) begin + if(~rst_n) sw_reset <= 1'b0; + else if(io_wr && io_address == 14) sw_reset <= io_writedata[2]; +end + +reg hob_pre; +always @(posedge clk) begin + if(reset) hob_pre <= 1'b0; + else if(io_wr && io_address == 14) hob_pre <= io_writedata[7]; +end + +reg hob; +always @(posedge clk) hob <= hob_pre & hob_ena[drv_addr[4]]; + +//------------------------------------------------------------------------------ + +wire write_data_io = io_wr && io_address == 0 && drq; +wire read_data_io = io_read && io_address == 0 && drq; + +wire io_done = (blk_size && io_cnt >= blk_size); +reg [13:0] io_cnt; +wire io_stb = read_data_io | write_data_io; + +always @(posedge clk) begin + reg old_stb, r_32; + old_stb <= io_stb; + + if(io_stb) r_32 <= io_32; + + if(reset) io_cnt <= 0; + else if(mgmt_write && mgmt_address == 5) io_cnt <= 0; + else if(old_stb & ~io_stb) io_cnt <= io_cnt + 1'd1 + r_32; +end + +reg [13:0] mgmt_cnt; +always @(posedge clk) begin + reg old_wr, old_rd; + + old_wr <= mgmt_write; + old_rd <= mgmt_read; + if((old_wr & ~mgmt_write) | (old_rd & ~mgmt_read)) begin + if(&mgmt_address) mgmt_cnt <= mgmt_cnt + 1'd1; + else mgmt_cnt <= 0; + end + + if(~rst_n) mgmt_cnt <= 0; +end + +wire n_data = (mgmt_cnt[13:1] <= io_cnt[13:1]) && drq && fast_read; +reg [1:0] n_data_r; +assign no_data = n_data || n_data_r; +always @(posedge clk) n_data_r <= {n_data_r[0], n_data}; + +wire [31:0] buf_readdata; +wire [31:0] buf_q; + +dpram #(12,16) io_buf0 +( + .clock(clk), + + .address_a(mgmt_cnt[12:1]), + .data_a(mgmt_writedata), + .wren_a(mgmt_write & &mgmt_address & ~mgmt_cnt[0]), + .q_a(buf_readdata[15:0]), + + .address_b(io_cnt[12:1]), + .data_b(io_writedata[15:0]), + .wren_b(write_data_io & (io_32 | ~io_cnt[0])), + .q_b(buf_q[15:0]) +); + +dpram #(12,16) io_buf1 +( + .clock(clk), + + .address_a(mgmt_cnt[12:1]), + .data_a(mgmt_writedata), + .wren_a(mgmt_write & &mgmt_address & mgmt_cnt[0]), + .q_a(buf_readdata[31:16]), + + .address_b(io_cnt[12:1]), + .data_b(io_32 ? io_writedata[31:16] : io_writedata[15:0]), + .wren_b(write_data_io & (io_32 | io_cnt[0])), + .q_b(buf_q[31:16]) +); + +//------------------------------------------------------------------------------ + +endmodule diff --git a/rtl/podule_ide.sv b/rtl/podule_ide.sv new file mode 100644 index 0000000..855f644 --- /dev/null +++ b/rtl/podule_ide.sv @@ -0,0 +1,87 @@ +// +// ide.sv +// +// Copyright (c) 2019 György Szombathelyi +// +// This source file is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This source file 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +// altera message_off 10030 +module podule_ide ( + input clk, // system clock. + input reset, + + input cpu_sel, + input cpu_we, + input [13:2] cpu_adr, + input [15:0] cpu_dat_i, + output [15:0] cpu_dat_o, + + output hdd_led, + + // place any signals that need to be passed up to the top after here. + output [5:0] ide_req, + input [4:0] ide_address, + input ide_write, + input [15:0] ide_writedata, + input ide_read, + output [15:0] ide_readdata +); + +// RISC Developments IDE Interface in Podule 0 +reg [7:0] rd_rom[16384]; +initial $readmemh("rtl/riscdevide_rom.hex", rd_rom); + +wire reg_sel = cpu_sel && cpu_adr[13:10] == 4'hA; +wire page_sel = cpu_sel && cpu_adr[13:02] == 12'h800 && cpu_we ; + +reg [2:0] rd_page; +always @(posedge clk) begin + if (reset) rd_page <= 0; + else if (page_sel) rd_page <= cpu_dat_i[2:0]; +end + +reg [7:0] rd_rom_q; +always @(posedge clk) rd_rom_q <= rd_rom[{rd_page, cpu_adr[12:2]}]; + +wire [2:0] ide_reg = cpu_adr[4:2]; +wire [15:0] data_out; + +assign cpu_dat_o = ~reg_sel ? {8'd0, rd_rom_q} : ((!ide_reg) ? data_out : { data_out[7:0], data_out[7:0] }); +assign ide_req[5:3] = 0; + +ide ide +( + .clk(clk), + .rst_n(~reset), + + .drq(hdd_led), + .use_fast(0), + .io_32(0), + + .io_address(ide_reg), + .io_read(~cpu_we & reg_sel), + .io_readdata(data_out), + .io_write(cpu_we & reg_sel), + .io_writedata(cpu_dat_i), + + .request(ide_req[2:0]), + .mgmt_address(ide_address[3:0]), + .mgmt_write(~ide_address[4] & ide_write), + .mgmt_writedata(ide_writedata), + .mgmt_read(~ide_address[4] & ide_read), + .mgmt_readdata(ide_readdata) +); + +endmodule