Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set Date/Time sim passes #4

Merged
merged 1 commit into from
Mar 15, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions bench/verilog/mdl_satacmd.v
Original file line number Diff line number Diff line change
@@ -20,12 +20,17 @@ module mdl_satacmd (
// }}}
);

localparam [127:0] COMMAND_RESPOND = {
{8'h00, 8'h77, 4'h0, 4'h0, 8'h27}, // ERROR | STATUS | RIRR | PMPORT | FIS TYPE (0x34)
{8'h00, 24'h000000}, // DEVICE | LBA[23:0]
{8'h00, 24'h000000}, // FEATURES[15:8] | LBA[47:24]
{8'h00 ,8'h00, 16'h0000} // CONTROL | ICC | COUNT[15:0]
};
// Remember ... the SATA spec is listed with byte 0 in bits [7:0],
// but we transmit big-endian, so byte 0 must be placed in the most
// significant bits. This will have the appearance of swapping byte
// order in words.
localparam [127:0] COMMAND_RESPOND = {
// FIS TYPE (0x34) | RIRR,PMPORT | STATUS | ERROR
{8'h34, 4'h0, 4'h0, 8'h77, 8'h00 },
{8'h00, 24'h000000}, // DEVICE | LBA[23:0]
{8'h00, 24'h000000}, // FEATURES[15:8] | LBA[47:24]
{8'h00 ,8'h00, 16'h0000} // CONTROL | ICC | COUNT[15:0]
};

reg known_cmd;
reg [2:0] cnt;
59 changes: 12 additions & 47 deletions bench/verilog/testscript/sata_commands.v
Original file line number Diff line number Diff line change
@@ -11,52 +11,17 @@ localparam [127:0] SET_DATE_TIME_EXT_CMD = {
{8'h00 ,8'h00, 16'h0000} // CONTROL | ICC | COUNT[15:0]
};

// task sdio_wait_while_busy;
// reg [31:0] read_data;
// reg prior_interrupt;
// begin

task testscript; // send_set_date_time_ext;
// input [47:0] timestamp; // Timestamp in milliseconds

reg [7:0] status; // Status output to check command result
reg [15:0] feature; // FEATURE field
reg [15:0] count; // COUNT field
reg [47:0] lba; // LBA field
reg [7:0] device; // DEVICE field
reg [7:0] command; // COMMAND field
reg [4:0] result; // Result from BFM functions

begin
@(posedge wb_clk);
while(wb_reset !== 1'b0)
@(posedge wb_clk);
@(posedge wb_clk);

// Initialize command fields
// feature = 16'h0000; // Reserved for SET DATE & TIME EXT
// count = 16'h0000; // Reserved for this command
// lba = timestamp; // Timestamp provided as input
// device = 8'h00; // Typically 0x00 for control commands
// command = 8'h77; // SET DATE & TIME EXT opcode

$display("Sending SET DATE & TIME EXT Command...");

// Send FEATURE field
u_bfm.writeio(ADDR_COUNT, SET_DATE_TIME_EXT_CMD[31:0]);
u_bfm.writeio(ADDR_LBAHI, SET_DATE_TIME_EXT_CMD[63:32]);
u_bfm.writeio(ADDR_LBALO, SET_DATE_TIME_EXT_CMD[95:64]);
u_bfm.write_f(ADDR_CMD, SET_DATE_TIME_EXT_CMD[127:96]);

// Wait for command completion and check status
$display("Waiting for command completion...");
wait(sata_int);
u_bfm.readio(ADDR_CMD, status);

if (status == 8'h50)
$display("SET DATE & TIME EXT command completed successfully.");
else
$display("SET DATE & TIME EXT command failed with status: %h", status);
end
endtask
// input [47:0] timestamp; // Timestamp in milliseconds
begin
// Initialize command fields
// feature = 16'h0000; // Reserved for SET DATE & TIME EXT
// count = 16'h0000; // Reserved for this command
// lba = timestamp; // Timestamp provided as input
// device = 8'h00; // Typically 0x00 for control commands
// command = 8'h77; // SET DATE & TIME EXT opcode

$display("Sending SET DATE & TIME EXT Command...");
sata_set_time(TIMESTAMP);
end endtask

41 changes: 39 additions & 2 deletions bench/verilog/testscript/sata_start.v
Original file line number Diff line number Diff line change
@@ -1,6 +1,43 @@
////////////////////////////////////////////////////////////////////////////////
//
// Filename: sata_start.v
// {{{
// Project: A Wishbone SATA controller
//
// Purpose: This module ... doesn't seem to have a purpose. It isn't
// (currently) part of any simulation, and may be removed in the
// future.
//
// Creator:
//
////////////////////////////////////////////////////////////////////////////////
// }}}
// Copyright (C) 2025, Gisselquist Technology, LLC
// {{{
// This file is part of the WBSATA project.
//
// The WBSATA project is a free software (firmware) project: you may
// 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 program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY 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, please see <http://www.gnu.org/licenses/> for a
// copy.
// }}}
// License: GPL, v3, as defined and found on www.gnu.org,
// {{{
// http://www.gnu.org/licenses/gpl.html
//
////////////////////////////////////////////////////////////////////////////////
//
`include "../testscript/satalib.v"


// }}}
module sata_soft_reset (
input wire clk, // Clock sinyali
input wire reset, // Reset sinyali
71 changes: 35 additions & 36 deletions bench/verilog/testscript/satalib.v
Original file line number Diff line number Diff line change
@@ -4,7 +4,8 @@
// {{{
// Project: A Wishbone SATA controller
//
// Purpose:
// Purpose: A library of functions to be used as helpers when writing
// test scripts.
//
// Creator:
//
@@ -35,7 +36,6 @@
////////////////////////////////////////////////////////////////////////////////
//
// }}}

localparam [ADDRESS_WIDTH-1:0]
ADDR_CMD = SATA_ADDR + 0,
ADDR_LBALO = SATA_ADDR + 4,
@@ -45,41 +45,40 @@ localparam [ADDRESS_WIDTH-1:0]
ADDR_HI = SATA_ADDR + 28,
ADDR_SATAPHY = DRP_ADDR + 0;

localparam [7:0] FIS_TYPE_REG_H2D = 8'h27; // Host to Device Register
localparam [7:0] FIS_TYPE_REG_D2H = 8'h34; // Device to Host Register
localparam [7:0] FIS_TYPE_DMA_ACT = 8'h39; // DMA Activate
localparam [7:0] FIS_TYPE_PIO = 8'h5F; // PIO Setup
localparam [7:0] FIS_TYPE_DATA = 8'h46; // Data FIS
localparam [7:0] FIS_TYPE_BIST = 8'h58; // BIST Activate
localparam [7:0] FIS_TYPE_SETBITS = 8'hA1; // Set Device Bits
localparam [7:0] FIS_TYPE_VENDOR = 8'hC7; // Vendor Specific
localparam [7:0] FIS_TYPE_REG_H2D = 8'h27, // Host to Device Register
FIS_TYPE_REG_D2H = 8'h34, // Device to Host Register
FIS_TYPE_DMA_ACT = 8'h39, // DMA Activate
FIS_TYPE_PIO = 8'h5F, // PIO Setup
FIS_TYPE_DATA = 8'h46, // Data FIS
FIS_TYPE_BIST = 8'h58, // BIST Activate
FIS_TYPE_SETBITS = 8'hA1, // Set Device Bits
FIS_TYPE_VENDOR = 8'hC7; // Vendor Specific

localparam [7:0] CMD_SET_DATETIME = 8'h77;

task send_sata_command(input [7:0] command);
begin
$display("Sending SATA command: %h", command);
// Burada komut gönderim mantığı implement edilir
end
endtask
task wait_response();
begin
$display("Waiting for response...");
// #10; // Simülasyon için bekleme süresi
wait(sata_int);
$display("Response received.");
end endtask

task send_data(input [31:0] data);
begin
$display("Sending data: %h", data);
// Burada veri gönderim mantığı implement edilir
end
endtask
task sata_set_time(input [47:0] timestamp);
reg [31:0] status;
begin
u_bfm.writeio(ADDR_COUNT, 32'h0);
u_bfm.writeio(ADDR_LBAHI, { 8'h0, timestamp[47:24] });
u_bfm.writeio(ADDR_LBALO, { 8'h0, timestamp[23: 0] });
u_bfm.writeio(ADDR_CMD, { 8'h0, CMD_SET_DATETIME, 8'h80,
FIS_TYPE_REG_H2D });

task receive_data(output [31:0] data);
begin
$display("Receiving data...");
// Burada veri alma mantığı implement edilir
data = 32'hDEADBEEF; // Simülasyon için örnek veri
end
endtask
wait(sata_int);
u_bfm.readio(ADDR_CMD, status);

task wait_response();
begin
$display("Waiting for response...");
#10; // Simülasyon için bekleme süresi
$display("Response received.");
end
endtask
if (status !== 32'h00_77_00_34)
begin
error_flag = 1'b1;
$display("SET DATE & TIME EXT command failed with status 0x%08x", status);
end
end endtask
3 changes: 2 additions & 1 deletion bench/verilog/wb_bfm.v
Original file line number Diff line number Diff line change
@@ -166,7 +166,8 @@ module wb_bfm #(
if (o_wb_cyc && i_wb_err)
err_flag <= 1'b1;
end wait(!i_clk);
while(!err_flag && o_wb_cyc);

while(!err_flag && o_wb_cyc)
begin
@(posedge i_clk)
begin
5 changes: 2 additions & 3 deletions rtl/sata_link.v
Original file line number Diff line number Diff line change
@@ -130,9 +130,8 @@ module sata_link #(

// 1. Remove any received continue and align primitives
// {{{
satalnk_rmcont #(
.P_CONT(P_CONT), .P_ALIGN(P_ALIGN)
) rm_align (
satalnk_rmcont
rm_align (
.i_clk(i_rx_clk), .i_reset(!rx_reset_n),
//
.i_valid(i_rx_valid), .i_primitive(i_rx_data[32]),
17 changes: 8 additions & 9 deletions rtl/satalnk_rmcont.v
Original file line number Diff line number Diff line change
@@ -38,10 +38,7 @@
`default_nettype none
`timescale 1ns/1ps
// }}}
module satalnk_rmcont #(
parameter [32:0] P_CONT = 33'h17caa9999,
P_ALIGN = 33'h1bc4a4a7b
) (
module satalnk_rmcont (
// {{{
input wire i_clk, i_reset,
//
@@ -57,6 +54,7 @@ module satalnk_rmcont #(

// Local declarations
// {{{
`include "sata_primitives.vh"
reg r_active, r_align;
reg [31:0] r_last;
// }}}
@@ -69,14 +67,16 @@ module satalnk_rmcont #(

if (i_valid && { i_primitive, i_data } == P_ALIGN)
o_valid <= 0;
if (i_valid && !i_primitive && r_active && r_align)
if (i_valid && !i_primitive && r_active)
o_valid <= 0;

if (i_valid && i_primitive)
begin
r_active <= 1'b0;
if (i_data[31:0] == P_CONT[31:0]) begin
r_active <= 1'b1;
o_data <= r_last;
o_valid <= 1'b0;
end else begin
r_last <= i_data;
r_align <= (i_data == P_ALIGN[31:0]);
@@ -86,8 +86,9 @@ module satalnk_rmcont #(
end
end else if (i_valid && r_active)
begin
// On any data, while P_CONT is active, repeat the last
// primitive
// On any data, while P_CONT is active, repeat the
// last primitive -- save that we'll drop o_valid,
// to make it easier to cross clock domains
o_data <= r_last;
end

@@ -97,6 +98,4 @@ module satalnk_rmcont #(
o_valid <= 0;
end
end


endmodule
62 changes: 33 additions & 29 deletions rtl/satatrn_fsm.v
Original file line number Diff line number Diff line change
@@ -169,6 +169,7 @@ module satatrn_fsm #(

reg s_sop, s_active;
reg [2:0] s_posn;
wire [31:0] s_brdata;

// Verilator lint_off UNUSED
wire SRST, BSY, DRDY, DF, DRQ, ERR;
@@ -180,6 +181,8 @@ module satatrn_fsm #(
assign DF = r_command[5];
assign DRQ = r_command[3];
assign ERR = r_command[0];

assign s_brdata = { s_data[7:0], s_data[15:8], s_data[23:16], s_data[31:24] };
// }}}

// cmd_type, known_cmd
@@ -322,7 +325,7 @@ module satatrn_fsm #(
if (i_reset)
s_active <= 0;
else if (s_pkt_valid && s_sop)
s_active <= (s_data[7:0] == FIS_REG_TO_HOST);
s_active <= (s_brdata[7:0] == FIS_REG_TO_HOST);

always @(posedge i_clk)
if (i_reset)
@@ -427,31 +430,31 @@ module satatrn_fsm #(
end else begin

if (s_pkt_valid && s_sop
&& ( s_data[7:0] == FIS_REG_TO_HOST
|| s_data[7:0] == FIS_SET_DEVBITS
|| s_data[7:0] == FIS_PIO_SETUP))
&& ( s_brdata[7:0] == FIS_REG_TO_HOST
|| s_brdata[7:0] == FIS_SET_DEVBITS
|| s_brdata[7:0] == FIS_PIO_SETUP))
begin
r_features[7:0] <= s_data[31:24]; // ERROR bits
r_command <= s_data[23:16]; // STATUS bits
r_int <= r_int || s_data[14];
r_features[7:0] <= s_brdata[31:24]; // ERROR bits
r_command <= s_brdata[23:16]; // STATUS bits
r_int <= r_int || s_brdata[14];
// The following bits are part of r_command
// BSY = s_data[23] = r_command[7]
// DRDY = s_data[22] = r_command[6]
// DF = s_data[21] = r_command[5]
// DRQ = s_data[19] = r_command[4]
// ERR = s_data[15]
last_fis <= s_data[7:0];
// BSY = s_brdata[23] = r_command[7]
// DRDY = s_brdata[22] = r_command[6]
// DF = s_brdata[21] = r_command[5]
// DRQ = s_brdata[19] = r_command[4]
// ERR = s_brdata[15]
last_fis <= s_brdata[7:0];
end

if (s_pkt_valid && s_sop && ( s_data[7:0] == FIS_DMA_SETUP))
r_int <= r_int || s_data[14];
if (s_pkt_valid && s_sop && ( s_brdata[7:0] == FIS_DMA_SETUP))
r_int <= r_int || s_brdata[14];

if (s_pkt_valid && s_active && s_posn == 1)
{ r_device, r_lba[23:0] } <= s_data;
{ r_device, r_lba[23:0] } <= s_brdata;
if (s_pkt_valid && s_active && s_posn == 2)
r_lba[47:24] <= s_data[23:0];
r_lba[47:24] <= s_brdata[23:0];
if (s_pkt_valid && s_active && s_posn == 3)
r_count <= s_data[15:0];
r_count <= s_brdata[15:0];

return_to_idle <= 1'b0;
r_dma_fail <= r_dma_fail || i_mm2s_err || i_s2mm_err;
@@ -577,15 +580,15 @@ module satatrn_fsm #(
// Receive data via PIO
last_rx_fis <= 1'b0;
if (s_pkt_valid && s_sop
&& s_data[7:0] == FIS_REG_TO_HOST)
&& s_brdata[7:0] == FIS_REG_TO_HOST)
begin
return_to_idle <= 1'b1;
fsm_state <= FSM_IDLE;
end else if (s_pkt_valid && s_sop
&& s_data[7:0] == FIS_PIO_SETUP)
&& s_brdata[7:0] == FIS_PIO_SETUP)
begin
fsm_state <= FSM_PIO_RXDATA;
last_rx_fis <= s_data[23]; // BSY
last_rx_fis <= s_brdata[23]; // BSY
end end
// }}}
FSM_PIO_RXDATA: begin
@@ -599,7 +602,7 @@ module satatrn_fsm #(
end
o_s2mm_request <= 1;
if (s_pkt_valid && s_sop
&& s_data[7:0] == FIS_REG_TO_HOST)
&& s_brdata[7:0] == FIS_REG_TO_HOST)
begin
fsm_state <= (last_rx_fis) ? FSM_IDLE : FSM_PIO_IN_SETUP;
if (last_rx_fis)
@@ -609,12 +612,12 @@ module satatrn_fsm #(
FSM_PIO_OUT_SETUP: begin
// {{{
// Transmit data via PIO
if (s_pkt_valid && s_sop && s_data[7:0] == FIS_REG_TO_HOST)
if (s_pkt_valid && s_sop && s_brdata[7:0] == FIS_REG_TO_HOST)
begin
fsm_state <= FSM_IDLE;
return_to_idle <= 1'b1;
end else if (s_pkt_valid && s_sop
&& s_data[7:0] == FIS_PIO_SETUP)
&& s_brdata[7:0] == FIS_PIO_SETUP)
begin
fsm_state <= FSM_PIO_TXDATA;
o_tran_req <= 1;
@@ -637,7 +640,7 @@ module satatrn_fsm #(
if (i_s2mm_beat)
o_s2mm_addr <= o_s2mm_addr + 4;
if (s_pkt_valid && s_sop
&& s_data[7:0] == FIS_REG_TO_HOST)
&& s_brdata[7:0] == FIS_REG_TO_HOST)
fsm_state <= FSM_DMA_IN_FINAL;
end
// }}}
@@ -656,12 +659,12 @@ module satatrn_fsm #(
o_tran_src <= SRC_MM2S;
o_tran_len <= (dma_length > 2048) ? 2048 : dma_length[LGLENGTH:0];
if (s_pkt_valid && s_sop
&& s_data[7:0] == FIS_REG_TO_HOST)
&& s_brdata[7:0] == FIS_REG_TO_HOST)
begin
fsm_state <= FSM_IDLE;
return_to_idle <= 1'b1;
end else if (s_pkt_valid && s_sop
&& s_data[7:0] == FIS_DMA_ACTIVATE)
&& s_brdata[7:0] == FIS_DMA_ACTIVATE)
begin
fsm_state <= FSM_DMA_TXDATA;
o_mm2s_request <= 1;
@@ -683,7 +686,7 @@ module satatrn_fsm #(
// {{{
o_tran_src <= SRC_MM2S;
if (s_pkt_valid && s_sop
&& s_data[7:0] == FIS_REG_TO_HOST)
&& s_brdata[7:0] == FIS_REG_TO_HOST)
begin
fsm_state <= FSM_IDLE;
return_to_idle <= 1'b1;
@@ -709,7 +712,8 @@ module satatrn_fsm #(
reg [1:0] m_count;

always @(posedge i_clk)
if (i_reset || o_tran_req || o_tran_src == SRC_REGS) begin
if (i_reset || o_tran_req || o_tran_src == SRC_REGS)
begin
{ m_valid, m_count } <= 0;
m_last <= i_reset;
end else if (!m_valid || m_ready)