OpenCores
URL https://opencores.org/ocsvn/nysa_sata/nysa_sata/trunk

Subversion Repositories nysa_sata

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 3 to Rev 4
    Reverse comparison

Rev 3 → Rev 4

/nysa_sata/trunk/rtl/link/sata_link_layer_write.v
30,7 → 30,7
`define DHOLD_DELAY 8
`define DHOLD_DELAY_EN 0
 
module sata_link_layer_write(
module sata_link_layer_write (
 
input rst, //reset
input clk,
83,24 → 83,23
output reg [12:0] d_count,
output reg [12:0] write_count,
output reg [3:0] buffer_pos
 
);
 
//Primatives
parameter IDLE = 4'h0;
localparam IDLE = 4'h0;
 
//fstate
parameter FIRST_DATA = 4'h1;
parameter ENQUEUE = 4'h2;
parameter LAST_DATA = 4'h3;
parameter WRITE_CRC = 4'h4;
parameter WAIT = 4'h5;
localparam FIRST_DATA = 4'h1;
localparam ENQUEUE = 4'h2;
localparam LAST_DATA = 4'h3;
localparam WRITE_CRC = 4'h4;
localparam WAIT = 4'h5;
 
//state
parameter WRITE_START = 4'h1;
parameter WRITE = 4'h2;
parameter WRITE_END = 4'h3;
parameter WAIT_RESPONSE = 4'h4;
localparam WRITE_START = 4'h1;
localparam WRITE = 4'h2;
localparam WRITE_END = 4'h3;
localparam WAIT_RESPONSE = 4'h4;
 
//Registers/Wires
reg [31:0] post_align_data;
175,7 → 174,6
.doutb (rd_dout )
);
 
 
scrambler scr (
.rst (scr_rst ),
.clk (clk ),
184,7 → 182,8
.din (scr_din ),
.dout (scr_dout )
);
crc c (
 
crc crc_inst (
//reset the CRC any time we're in IDLE
.rst (scr_rst ),
.clk (clk ),
/nysa_sata/trunk/sim/simple_tb.v
1,8 → 1,11
`timescale 1ns/1ps
 
`define SCLK_HALF_PERIOD 3
`define DCLK_HALF_PERIOD 3
//`define DCLK_HALF_PERIOD 2 //Change to any frequency you want
 
`define SCLK_PERIOD (2 * `SCLK_HALF_PERIOD)
`define DCLK_PERIOD (2 * `DCLK_HALF_PERIOD)
 
`define STARTUP_TIMEOUT 32'h00000100
`define ERROR_TIMEOUT 32'h00000100
15,30 → 18,24
//Parameters
//Registers/Wires
reg rst = 0; //reset
reg clk = 0;
reg sata_clk = 0;
reg data_clk = 0;
 
wire command_layer_reset;
 
wire linkup; //link is finished
wire sata_ready;
wire busy;
wire sata_busy;
 
wire send_sync_escape;
wire hard_drive_error;
wire pio_data_ready;
 
reg write_data_en;
reg read_data_en;
 
reg soft_reset_en = 0;
reg [15:0] sector_count = 8;
reg [47:0] sector_address = 0;
 
wire d2h_interrupt;
wire d2h_notification;
wire [3:0] d2h_port_mult;
wire [7:0] d2h_device;
wire [47:0] d2h_lba;
wire [15:0] d2h_sector_count;
wire [7:0] d2h_status;
wire [7:0] d2h_error;
 
 
reg [31:0] user_din;
reg user_din_stb;
wire [1:0] user_din_ready;
57,13 → 54,13
wire phy_ready;
 
wire [31:0] tx_dout;
wire tx_isk;
wire tx_is_k;
wire tx_comm_reset;
wire tx_comm_wake;
wire tx_elec_idle;
 
wire [31:0] rx_din;
wire [3:0] rx_isk;
wire [3:0] rx_is_k;
wire rx_elec_idle;
wire comm_init_detect;
wire comm_wake_detect;
78,6 → 75,7
wire rx_is_elec_idle;
wire hd_ready;
wire platform_ready;
wire platform_error;
 
//Debug
wire [31:0] hd_data_to_host;
84,147 → 82,259
 
reg [23:0] din_count;
reg [23:0] dout_count;
reg hold;
reg hold = 0;
 
reg single_rdwr = 0;
reg [7:0] sata_command = 0;
reg [15:0] user_features = 0;
 
 
reg clk = 0;
wire dma_activate_stb;
wire d2h_reg_stb;
wire pio_setup_stb;
wire d2h_data_stb;
wire dma_setup_stb;
wire set_device_bits_stb;
 
wire [7:0] d2h_fis;
wire d2h_interrupt;
wire d2h_notification;
wire [3:0] d2h_port_mult;
wire [7:0] d2h_device;
wire [47:0] d2h_lba;
wire [15:0] d2h_sector_count;
wire [7:0] d2h_status;
wire [7:0] d2h_error;
 
 
reg r_u2h_write_enable = 0;
reg r_h2u_read_enable = 0;
 
reg sata_execute_command_stb = 0;
wire [31:0] hd_data_from_host;
wire hd_read_from_host;
wire hd_write_to_host;
 
//hd data reader core
hd_data_reader user_2_hd_reader(
.clk (clk ),
.rst (rst ),
.enable (r_u2h_write_enable ),
.error (u2h_read_error ),
 
.hd_read_from_host (hd_read_from_host ),
.hd_data_from_host (hd_data_from_host )
);
 
//hd data writer core
hd_data_writer hd_2_user_generator(
.clk (clk ),
.rst (rst ),
.enable (r_h2u_read_enable ),
.data (hd_data_to_host ),
.strobe (hd_write_to_host )
);
 
//Submodules
 
sata_stack ss (
.rst (rst ), //reset
.clk (sata_clk ), //clock used to run the stack
.data_in_clk (sata_clk ),
.data_out_clk (sata_clk ),
.clk (sata_clk ), //clock used to run the stack
.rst (rst ), //reset
 
.platform_ready (platform_ready ), //the underlying physical platform is
.linkup (linkup ), //link is finished
.sata_ready (sata_ready ),
.command_layer_reset (command_layer_reset ), //Reset the command layer and send a software reset to the hard drive
 
.platform_ready (platform_ready ), //the underlying physical platform is ready
.platform_error (platform_error ), //some bad thing happend at the transceiver level
.linkup (linkup ), //link is finished
 
.busy (busy ),
.sata_ready (sata_ready ), //Hard drive is ready for commands
.sata_busy (sata_busy ), //Hard drive is busy executing commands
 
.send_sync_escape (send_sync_escape ), //This is a way to escape from a running transaction
.hard_drive_error (hard_drive_error ),
 
.write_data_en (write_data_en ),
.single_rdwr (single_rdwr ),
.read_data_en (read_data_en ),
 
.send_user_command_stb (1'b0 ),
.soft_reset_en (soft_reset_en ),
.command (1'b0 ),
.pio_data_ready (pio_data_ready ), //Peripheral IO has some data ready
 
.sector_count (sector_count ),
.sector_address (sector_address ),
//Host to Device Control
.hard_drive_command (sata_command ), //Hard Drive commands EX: DMA Read 0x25, DMA Write 0x35
.execute_command_stb (sata_execute_command_stb),
.user_features (user_features ),
.sector_count (sector_count ),
.sector_address (sector_address ),
 
.d2h_interrupt (d2h_interrupt ),
.d2h_notification (d2h_notification ),
.d2h_port_mult (d2h_port_mult ),
.d2h_device (d2h_device ),
.d2h_lba (d2h_lba ),
.d2h_sector_count (d2h_sector_count ),
.d2h_status (d2h_status ),
.d2h_error (d2h_error ),
.dma_activate_stb (dma_activate_stb ),
.d2h_reg_stb (d2h_reg_stb ),
.pio_setup_stb (pio_setup_stb ),
.d2h_data_stb (d2h_data_stb ),
.dma_setup_stb (dma_setup_stb ),
.set_device_bits_stb (set_device_bits_stb ),
 
.user_din (user_din ),
.user_din_stb (user_din_stb ),
.user_din_ready (user_din_ready ),
.user_din_activate (user_din_activate ),
.user_din_size (user_din_size ),
.d2h_fis (d2h_fis ),
.d2h_interrupt (d2h_interrupt ),
.d2h_notification (d2h_notification ),
.d2h_port_mult (d2h_port_mult ),
.d2h_device (d2h_device ),
.d2h_lba (d2h_lba ),
.d2h_sector_count (d2h_sector_count ),
.d2h_status (d2h_status ),
.d2h_error (d2h_error ),
 
.user_dout (user_dout ),
.user_dout_ready (user_dout_ready ),
.user_dout_activate (user_dout_activate ),
.user_dout_stb (user_dout_stb ),
.user_dout_size (user_dout_size ),
//Data from host to the hard drive path
.data_in_clk (data_clk ), //Any clock to send data to the hard drive
.data_in_clk_valid (1'b1 ), //the data in clock is valid
.user_din (user_din ), //32-bit data to clock into FIFO
.user_din_stb (user_din_stb ), //Strobe to clock data into FIFO
.user_din_ready (user_din_ready ), //If one of the 2 in FIFOs are ready
.user_din_activate (user_din_activate ), //Activate one of the 2 FIFOs
.user_din_size (user_din_size ), //Number of available spots within the FIFO
.user_din_empty (user_din_empty ),
 
.transport_layer_ready (transport_layer_ready),
.link_layer_ready (link_layer_ready ),
.phy_ready (phy_ready ),
//Data from hard drive to host path
.data_out_clk (data_clk ),
.data_out_clk_valid (1'b1 ), //the data out clock is valid
.user_dout (user_dout ), //Actual data the comes from FIFO
.user_dout_ready (user_dout_ready ), //The output FIFO is ready (see below for how to use)
.user_dout_activate (user_dout_activate ), //Activate a FIFO (See below for an example on how to use)
.user_dout_stb (user_dout_stb ), //Strobe the data out of the FIFO (first word is available before strobe)
.user_dout_size (user_dout_size ), //Number of 32-bit words available
 
.tx_dout (tx_dout ),
.tx_isk (tx_isk ),
.tx_comm_reset (tx_comm_reset ),
.tx_comm_wake (tx_comm_wake ),
.tx_elec_idle (tx_elec_idle ),
.transport_layer_ready (transport_layer_ready ),
.link_layer_ready (link_layer_ready ),
.phy_ready (phy_ready ), //sata phy layer has linked up and communication simple comm started
.phy_error (1'b0 ), //an error on the transcievers has occured
 
.rx_din (rx_din ),
.rx_isk (rx_isk ),
.rx_elec_idle (rx_elec_idle ),
.comm_init_detect (comm_init_detect ),
.comm_wake_detect (comm_wake_detect ),
.rx_byte_is_aligned (rx_byte_is_aligned ),
//Interface to the gigabit transcievers
.tx_dout (tx_dout ),
.tx_is_k (tx_is_k ),
.tx_comm_reset (tx_comm_reset ),
.tx_comm_wake (tx_comm_wake ),
.tx_elec_idle (tx_elec_idle ),
.tx_oob_complete (1'b1 ),
 
.rx_din (rx_din ),
.rx_is_k (rx_is_k ),
.rx_elec_idle (1'b0 ),
.rx_byte_is_aligned (rx_byte_is_aligned ),
.comm_init_detect (comm_init_detect ),
.comm_wake_detect (comm_wake_detect ),
 
.prim_scrambler_en (prim_scrambler_en ),
.data_scrambler_en (data_scrambler_en )
//These should be set to 1 for normal operations, while debugging you can set to 0 to help debug things
.prim_scrambler_en (prim_scrambler_en ),
.data_scrambler_en (data_scrambler_en ),
 
.dbg_cc_lax_state ( ),
.dbg_cw_lax_state (command_write_state ),
 
.dbg_t_lax_state (transport_state ),
 
.dbg_li_lax_state ( ),
.dbg_lr_lax_state ( ),
.dbg_lw_lax_state (ll_write_state ),
.dbg_lw_lax_fstate ( ),
 
 
.dbg_ll_write_ready ( ),
.dbg_ll_paw ( ),
.dbg_ll_send_crc ( ),
 
.oob_state (oob_state ),
 
.dbg_detect_sync ( ),
.dbg_detect_r_rdy ( ),
.dbg_detect_r_ip ( ),
.dbg_detect_r_ok (dbg_detect_r_ok ),
.dbg_detect_r_err (dbg_detect_r_err ),
.dbg_detect_x_rdy ( ),
.dbg_detect_sof ( ),
.dbg_detect_eof ( ),
.dbg_detect_wtrm ( ),
.dbg_detect_cont ( ),
.dbg_detect_hold ( ),
.dbg_detect_holda ( ),
.dbg_detect_align ( ),
.dbg_detect_preq_s ( ),
.dbg_detect_preq_p ( ),
.dbg_detect_xrdy_xrdy ( ),
 
.dbg_send_holda ( ),
 
// .slw_in_data_addra (slw_in_data_addra ),
// .slw_d_count (slw_d_count ),
// .slw_write_count (slw_write_count ),
// .slw_buffer_pos (slw_buffer_pos )
 
.slw_in_data_addra ( ),
.slw_d_count ( ),
.slw_write_count ( ),
.slw_buffer_pos ( )
 
);
 
faux_sata_hd fshd (
.rst (rst ),
.clk (sata_clk ),
.tx_dout (rx_din ),
.tx_isk (rx_isk ),
.rst (rst ),
.clk (sata_clk ),
.tx_dout (rx_din ),
.tx_is_k (rx_is_k ),
 
.rx_din (tx_dout ),
.rx_isk ({3'b000, tx_isk} ),
.rx_is_elec_idle (tx_elec_idle ),
.rx_byte_is_aligned (rx_byte_is_aligned ),
.rx_din (tx_dout ),
.rx_is_k ({3'b000, tx_is_k} ),
.rx_is_elec_idle (tx_elec_idle ),
.rx_byte_is_aligned (rx_byte_is_aligned ),
 
.comm_reset_detect (tx_comm_reset ),
.comm_wake_detect (tx_comm_wake ),
.comm_reset_detect (tx_comm_reset ),
.comm_wake_detect (tx_comm_wake ),
 
.tx_comm_reset (comm_init_detect ),
.tx_comm_wake (comm_wake_detect ),
.tx_comm_reset (comm_init_detect ),
.tx_comm_wake (comm_wake_detect ),
 
.hd_ready (hd_ready ),
// .phy_ready (phy_ready ),
.hd_ready (hd_ready ),
// .phy_ready (phy_ready ),
 
 
.dbg_data_scrambler_en (data_scrambler_en ),
.dbg_data_scrambler_en (data_scrambler_en ),
 
.dbg_hold (hold ),
.dbg_hold (hold ),
 
.dbg_ll_write_start (0 ),
.dbg_ll_write_data (0 ),
.dbg_ll_write_size (0 ),
.dbg_ll_write_hold (0 ),
.dbg_ll_write_abort (0 ),
.dbg_ll_write_start (0 ),
.dbg_ll_write_data (0 ),
.dbg_ll_write_size (0 ),
.dbg_ll_write_hold (0 ),
.dbg_ll_write_abort (0 ),
 
.dbg_ll_read_ready (0 ),
.dbg_t_en (0 ),
.dbg_ll_read_ready (0 ),
.dbg_t_en (0 ),
 
.dbg_send_reg_stb (0 ),
.dbg_send_dma_act_stb (0 ),
.dbg_send_data_stb (0 ),
.dbg_send_pio_stb (0 ),
.dbg_send_dev_bits_stb (0 ),
.dbg_send_reg_stb (0 ),
.dbg_send_dma_act_stb (0 ),
.dbg_send_data_stb (0 ),
.dbg_send_pio_stb (0 ),
.dbg_send_dev_bits_stb (0 ),
 
.dbg_pio_transfer_count(0 ),
.dbg_pio_direction (0 ),
.dbg_pio_e_status (0 ),
.dbg_pio_transfer_count(0 ),
.dbg_pio_direction (0 ),
.dbg_pio_e_status (0 ),
 
.dbg_d2h_interrupt (0 ),
.dbg_d2h_notification (0 ),
.dbg_d2h_status (0 ),
.dbg_d2h_error (0 ),
.dbg_d2h_port_mult (0 ),
.dbg_d2h_device (0 ),
.dbg_d2h_lba (0 ),
.dbg_d2h_sector_count (0 ),
.dbg_d2h_interrupt (0 ),
.dbg_d2h_notification (0 ),
.dbg_d2h_status (0 ),
.dbg_d2h_error (0 ),
.dbg_d2h_port_mult (0 ),
.dbg_d2h_device (0 ),
.dbg_d2h_lba (0 ),
.dbg_d2h_sector_count (0 ),
 
.dbg_cl_if_data (0 ),
.dbg_cl_if_ready (0 ),
.dbg_cl_if_size (0 ),
.dbg_cl_of_ready (0 ),
.dbg_cl_of_size (0 ),
.hd_data_to_host (hd_data_to_host )
.dbg_cl_if_data (0 ),
.dbg_cl_if_ready (0 ),
.dbg_cl_if_size (0 ),
.dbg_cl_of_ready (0 ),
.dbg_cl_of_size (0 ),
 
.hd_read_from_host (hd_read_from_host ),
.hd_data_from_host (hd_data_from_host ),
 
.hd_write_to_host (hd_write_to_host ),
.hd_data_to_host (hd_data_to_host )
 
);
 
 
233,22 → 343,25
assign prim_scrambler_en = 1;
assign data_scrambler_en = 1;
assign platform_ready = 1;
assign hd_data_to_host = 32'h01234567;
//assign hd_data_to_host = 32'h01234567;
assign send_sync_escape = 1'b0;
assign command_layer_reset = 1'b0;
 
 
//Synchronous Logic
always #`SCLK_HALF_PERIOD sata_clk = ~sata_clk;
always #`DCLK_HALF_PERIOD data_clk = ~data_clk;
always #1 clk = ~clk;
 
//Simulation Control
initial begin
rst <= 1;
$dumpfile ("design.vcd");
$dumpvars(0, simple_tb);
//$dumpfile ("design.vcd");
//$dumpvars(0, simple_tb);
#(20 * `SCLK_PERIOD);
rst <= 0;
#40000;
$finish();
//#(20 * `SCLK_PERIOD);
//$finish();
end
 
 
256,51 → 369,71
initial begin
sector_address <= 0;
sector_count <= 8;
write_data_en <= 0;
read_data_en <= 0;
single_rdwr <= 0;
 
sata_command <= 0;
user_features <= 0;
 
r_u2h_write_enable <= 0;
r_h2u_read_enable <= 0;
sata_execute_command_stb <= 0;
 
#(20 * `SCLK_PERIOD);
while (!linkup) begin
#1;
#(1 * `SCLK_PERIOD);
end
while (busy) begin
#1;
while (!sata_ready) begin
#(1 * `SCLK_PERIOD);
end
//Send a command
// #(700 * `SCLK_PERIOD);
#(563 * `SCLK_PERIOD);
write_data_en <= 1;
//#(563 * `SCLK_PERIOD);
#(100 * `SCLK_PERIOD);
sata_command <= 8'h35; //Write
sector_count <= 1;
#(1 * `SCLK_PERIOD);
sata_execute_command_stb <= 1;
#(1 * `SCLK_PERIOD);
sata_execute_command_stb <= 0;
r_u2h_write_enable <= 1; //Read Data on the Hard Drive Side
 
 
#(1000 * `SCLK_PERIOD);
while (!busy) begin
#1;
while (sata_busy) begin
#(1 * `SCLK_PERIOD);
end
write_data_en <= 0;
#(100 * `SCLK_PERIOD);
r_u2h_write_enable <= 0;
 
 
while (busy) begin
#1;
end
 
#(200 * `SCLK_PERIOD);
write_data_en <= 1;
//read_data_en <= 1;
 
//Put some data in the virtual hard drive
r_h2u_read_enable <= 1;
#(1000 * `SCLK_PERIOD);
sector_count <= 2;
sata_command <= 8'h25; //Read
#(1 * `SCLK_PERIOD);
sata_execute_command_stb <= 1;
#(1 * `SCLK_PERIOD);
sata_execute_command_stb <= 0;
 
 
#(1000 * `SCLK_PERIOD);
#(20 * `SCLK_PERIOD);
while (!busy) begin
while (sata_busy) begin
#1;
end
write_data_en <= 1;
//read_data_en <= 0;
 
 
 
r_h2u_read_enable <= 0;
//$finish();
end
 
/*
initial begin
hold <= 0;
#(20 * `SCLK_PERIOD);
while (!write_data_en) begin
while (!sata_busy) begin
#1;
end
#(800* `SCLK_PERIOD);
308,6 → 441,7
#(100 * `SCLK_PERIOD);
hold <= 0;
end
*/
/*
//inject a hold
initial begin
328,8 → 462,6
initial begin
sector_address <= 0;
sector_count <= 0;
write_data_en <= 0;
read_data_en <= 0;
 
#(20 * `SCLK_PERIOD);
while (!linkup) begin
349,8 → 481,17
end
*/
 
 
 
 
 
 
 
 
 
 
//Buffer Fill/Drain
always @ (posedge sata_clk) begin
always @ (posedge data_clk) begin
if (rst) begin
user_din <= 0;
user_din_stb <= 0;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.