module disk2(addr,devsel, MISO, MOSI, CLK, MISO_m, MOSI_m, CLK_m, ss_m,//cs_n, status, rw, data, int0, /*ser_o*/ spi_mode,extra, RDY); input [3:0] addr; input devsel; input MOSI, CLK; // input cs_n; input status; input rw; inout [7:0] data; output MISO,int0; output MOSI_m, CLK_m, ss_m; input MISO_m; //output [3:0]; output extra, RDY;//,D6,D7; input [1:0] spi_mode; // input Q3; // reg [7:0] disk_data = 8'b0; // reg [7:0] latched_addr; wire [7:0] disk_data; reg ser_in; // reg MISO_reg; //wire ser_out; reg Q6 = 0; reg Q7 = 0; reg ON; reg disk2; wire phase_access; wire data_read_access; wire high_bit; wire cs_n; reg had_access; //reg status_reg; assign cs_n = ~spi_mode[1]; assign ss_m = ~spi_mode[0]; //assign D6= disk_data[6]; //assign D7= disk_data[7]; assign MOSI_m = MOSI; // just level conversion assign CLK_m = spi_mode[0] ? CLK : 1'b0; //assign MISO = spi_mode[0] ? MISO_m : latched_addr[7]; //MISO_reg; // if addr[3] is 0, it is a "phase" access, so we can use read of c0x0 for status assign high_bit = (cs_n && ON) ? ( addr[3] ? disk_data[7] : status) : 1'b0; // no data while update in progress or disk is "OFF" assign data = ((devsel == 0) && (addr[0] == 0) && (rw == 1)) ? {high_bit, disk_data[6:0]} : 8'bz; assign int0 = had_access && devsel; // for polling // create an interrupt on writes and some reads wire int_event; assign int_event = //phase_access || data_read_access || (rw == 0); assign RDY = spi_mode[1] ? 1'b0 : 1'bz; // assign int0 = int_event && ~devsel; // for interrupt // assign ser_out = sel ? latched_addr[5] : disk_data[7]; // assign had_access = latched_addr[5]; //assign debug = disk_data[3:0]; assign ser_o = high_bit; assign phase_access = (addr[3] == 1'b0); assign data_read_access = (addr == 4'b1100); assign extra = ~devsel && phase_access && addr[0]; // phase is ON always @(posedge CLK ) begin // if (spi_mode[1]) begin if(spi_mode[0]) // special mode reading directly from memory ser_in <= MISO_m; else ser_in <= MOSI; // end end /* always @(posedge CLK ) begin if(status) status_reg <= MOSI; end */ always @(negedge devsel) begin case (addr[3:1]) 3'b110: // co8c,x c08d,x Q6 <= addr[0]; 3'b111: // co8e,x c08f,x Q7 <= addr[0]; 3'b100: ON <= addr[0]; 3'b101: disk2 <= addr[0]; endcase end wire set_int; assign set_int = int_event & ~spi_mode[1] & ~devsel; always @(negedge CLK or posedge set_int) begin if(set_int) had_access <= 1'b1; else had_access <= 1'b0; end wire ALOAD_DATA; wire ALOAD_ADDR; wire so_data, SO; assign ALOAD_DATA = ~rw & ~devsel & ~spi_mode[1]; assign ALOAD_ADDR = ~devsel & ~spi_mode[1]; assign MISO = spi_mode[0] ? MISO_m : SO; //MISO_reg; `define USE_SHIFTER `ifdef USE_SHIFTER shift data_shifter ( .C(CLK), .ALOAD(ALOAD_DATA), .enable(spi_mode[1]), .SI(ser_in), .D(data), .SO(so_data), .par_out(disk_data) ); shift address_shifter ( .C(CLK), .ALOAD(ALOAD_ADDR), .enable(spi_mode[1]), .SI(so_data), .D({Q7, Q6, disk2, rw, addr}), .SO(SO) ); `else always @(negedge CLK or negedge devsel) begin if(devsel == 0) begin if (cs_n == 1) begin // don't write in the middle of a transaction latched_addr <= {Q7, Q6, disk2, rw, addr}; had_access <= int_event; if(rw == 0) disk_data <= data; end end else begin if (cs_n == 0) begin disk_data <= {disk_data[6:0], ser_in} ; latched_addr <= {latched_addr[6:0], disk_data[7]}; //MISO_reg <= latched_addr[7]; had_access <= 0; end end end `endif endmodule