mirror of
https://github.com/MiSTer-devel/Archie_MiSTer.git
synced 2026-05-17 03:03:15 +00:00
Use standard IDE interface and module.
This commit is contained in:
45
Archie.sv
45
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 ),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
122
rtl/hps_ext.v
122
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
|
||||
|
||||
169
rtl/ide.sv
169
rtl/ide.sv
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
// 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
|
||||
314
rtl/ide.v
Normal file
314
rtl/ide.v
Normal file
@@ -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
|
||||
87
rtl/podule_ide.sv
Normal file
87
rtl/podule_ide.sv
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
// 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
|
||||
Reference in New Issue
Block a user