Commit 1aebe5e1 authored by Alexey Grebenkin's avatar Alexey Grebenkin

Complete host intermediate commit, pre-testing

parent be827c35
......@@ -40,7 +40,73 @@ module dma_regs #(
input wire [3:0] bram_wstb,
input wire bram_wen,
input wire bram_ren,
input wire bram_regen
input wire bram_regen,
// tmp to cmd control
output wire cmd_val_out,
output wire [31:0] cmd_out,
// tmp to shadow registers
output wire [31:0] sh_data, // write data
output wire sh_data_val, // write strobe
output wire sh_data_strobe, // read strobe
output wire [15:0] sh_feature,
output wire sh_feature_val,
output wire [23:0] sh_lba_lo,
output wire sh_lba_lo_val,
output wire [23:0] sh_lba_hi,
output wire sh_lba_hi_val,
output wire [15:0] sh_count,
output wire sh_count_val,
output wire [7:0] sh_command,
output wire sh_command_val,
output wire [7:0] sh_dev,
output wire sh_dev_val,
output wire [7:0] sh_control,
output wire sh_control_val,
output wire [31:0] sh_dma_id_lo
output wire sh_dma_id_lo_val,
output wire [31:0] sh_dma_id_hi,
output wire sh_dma_id_hi_val,
output wire [31:0] sh_buf_off,
output wire sh_buf_off_val,
output wire [31:0] sh_dma_cnt,
output wire sh_dma_cnt_val,
output wire [31:0] sh_tran_cnt,
output wire sh_tran_cnt_val,
output wire sh_autoact,
output wire sh_autoact_val,
output wire sh_inter,
output wire sh_inter_val,
output wire [3:0] sh_port,
output wire sh_port_val,
output wire sh_notif,
output wire sh_notif_val,
output wire sh_dir,
output wire sh_dir_val,
// inputs from sh registers
input wire sh_data_val_in,
input wire [31:0] sh_data_in,
input wire [7:0] sh_control_in,
input wire [15:0] sh_feature_in,
input wire [47:0] sh_lba_in,
input wire [15:0] sh_count_in,
input wire [7:0] sh_command_in,
input wire [7:0] sh_err_in,
input wire [7:0] sh_status_in,
input wire [7:0] sh_estatus_in, // E_Status
input wire [7:0] sh_dev_in,
input wire [3:0] sh_port_in,
input wire sh_inter_in,
input wire sh_dir_in,
input wire [63:0] sh_dma_id_in,
input wire [31:0] sh_dma_off_in,
input wire [31:0] sh_dma_cnt_in,
input wire [15:0] sh_tran_cnt_in, // Transfer Count
input wire sh_notif_in,
input wire sh_autoact_in
// inputs from cmd control
input wire [31:0] cmd_in
);
//reg [32*REGISTERS_CNT - 1:0] mem;
/*
......@@ -86,7 +152,7 @@ pulse_cross_clock dma_start_pulse(
.busy ()
);
assign dma_start_aclk = bram_wen & (bram_waddr[3:0] == 4'h4) & |wdata;
assign dma_start_aclk = bram_wen & (bram_waddr[7:0] == 8'hf4) & |wdata;
assign wdata = bram_wdata[31:0] & {{8{bram_wstb[3]}}, {8{bram_wstb[2]}}, {8{bram_wstb[1]}}, {8{bram_wstb[0]}}};
always @ (posedge ACLK)
......@@ -99,26 +165,93 @@ assign dma_type = |reg0c;
always @ (posedge ACLK)
begin
reg00 <= rst ? 32'h0 : bram_wen & (bram_waddr[3:0] == 4'h0) ? wdata : reg00;
reg04 <= rst ? 32'h0 : bram_wen & (bram_waddr[3:0] == 4'h1) ? wdata : reg04;
reg08 <= rst ? 32'h0 : bram_wen & (bram_waddr[3:0] == 4'h2) ? wdata : reg08;
reg0c <= rst ? 32'h0 : bram_wen & (bram_waddr[3:0] == 4'h3) ? wdata : reg0c;
reg00 <= rst ? 32'h0 : bram_wen & (bram_waddr[7:0] == 8'hf0) ? wdata : reg00;
reg04 <= rst ? 32'h0 : bram_wen & (bram_waddr[7:0] == 8'hf1) ? wdata : reg04;
reg08 <= rst ? 32'h0 : bram_wen & (bram_waddr[7:0] == 8'hf2) ? wdata : reg08;
reg0c <= rst ? 32'h0 : bram_wen & (bram_waddr[7:0] == 8'hf3) ? wdata : reg0c;
reg10 <= rst ? 32'h0 : dma_start_aclk ? 32'h0 : dma_done_aclk ? 32'hffffffff : reg10; // status reg
reg14 <= rst ? 32'h0 : dma_done_aclk ? reg00 : reg14;
end
// writes to shadow registers:
assign sh_data_val = bram_wen & (bram_waddr[7:0] == 8'h0);
assign sh_feature_val = bram_wen & (bram_waddr[7:0] == 8'h1);
assign sh_lba_lo_val = bram_wen & (bram_waddr[7:0] == 8'h2);
assign sh_lba_hi_val = bram_wen & (bram_waddr[7:0] == 8'h3);
assign sh_count_val = bram_wen & (bram_waddr[7:0] == 8'h4);
assign sh_command_val = bram_wen & (bram_waddr[7:0] == 8'h5);
assign sh_dev_val = bram_wen & (bram_waddr[7:0] == 8'h6);
assign sh_control_val = bram_wen & (bram_waddr[7:0] == 8'h7);
assign sh_dma_id_lo_val = bram_wen & (bram_waddr[7:0] == 8'h8);
assign sh_dma_id_hi_val = bram_wen & (bram_waddr[7:0] == 8'h9);
assign sh_buf_off_val = bram_wen & (bram_waddr[7:0] == 8'ha);
assign sh_tran_cnt_val = bram_wen & (bram_waddr[7:0] == 8'hb);
assign sh_autoact_val = bram_wen & (bram_waddr[7:0] == 8'hc);
assign sh_inter_val = bram_wen & (bram_waddr[7:0] == 8'hd);
assign sh_dir_val = bram_wen & (bram_waddr[7:0] == 8'he);
assign cmd_val_out = bram_wen & (bram_waddr[7:0] == 8'hf);
assign sh_port = bram_wen & (bram_waddr[7:0] == 8'h13);
assign sh_dma_cnt_val = bram_wen & (bram_waddr[7:0] == 8'h14);
assign sh_notif_val = bram_wen & (bram_waddr[7:0] == 8'h15);
assign sh_data = wdata;
assign sh_feature = wdata;
assign sh_lba_lo = wdata;
assign sh_lba_hi = wdata;
assign sh_count = wdata;
assign sh_command = wdata;
assign sh_dev = wdata;
assign sh_control = wdata;
assign sh_dma_id_lo = wdata;
assign sh_dma_id_hi = wdata;
assign sh_buf_off = wdata;
assign sh_tran_cnt = wdata;
assign sh_autoact = wdata;
assign sh_inter = wdata;
assign sh_dir = wdata;
assign sh_port = wdata;
assign sh_notif = wdata;
assign sh_dma_cnt = wdata;
assign cmd_out = wdata;
assign sh_data_strobe = bram_regen & bram_raddr_r == 8'h00;
// read from registers. Interface's protocol assumes returning data with a delay
reg [3:0] bram_raddr_r;
reg [7:0] bram_raddr_r;
reg [31:0] bram_rdata_r;
always @ (posedge ACLK) begin
bram_raddr_r <= bram_ren ? bram_raddr[3:0] : bram_raddr_r;
bram_raddr_r <= bram_ren ? bram_raddr[7:0] : bram_raddr_r;
bram_rdata_r <= ~bram_regen ? bram_rdata_r :
bram_raddr_r == 4'h0 ? reg00 :
bram_raddr_r == 4'h1 ? reg04 :
bram_raddr_r == 4'h2 ? reg08 :
bram_raddr_r == 4'h3 ? reg0c :
bram_raddr_r == 4'h4 ? reg10 :
bram_raddr_r == 4'h5 ? reg14 :
bram_raddr_r == 8'hf0 ? reg00 :
bram_raddr_r == 8'hf1 ? reg04 :
bram_raddr_r == 8'hf2 ? reg08 :
bram_raddr_r == 8'hf3 ? reg0c :
bram_raddr_r == 8'hf4 ? reg10 :
bram_raddr_r == 8'hf5 ? reg14 :
bram_raddr_r == 8'h00 ? sh_data_in :
bram_raddr_r == 8'h01 ? sh_feature_in :
bram_raddr_r == 8'h02 ? sh_lba_in[23:0] :
bram_raddr_r == 8'h03 ? sh_lba_in[47:24] :
bram_raddr_r == 8'h04 ? sh_count_in :
bram_raddr_r == 8'h05 ? sh_command_in :
bram_raddr_r == 8'h06 ? sh_dev_in :
bram_raddr_r == 8'h07 ? sh_control_in :
bram_raddr_r == 8'h08 ? sh_dma_id_in[31:0] :
bram_raddr_r == 8'h09 ? sh_dma_id_in[63:32] :
bram_raddr_r == 8'h0a ? sh_dma_off_in :
bram_raddr_r == 8'h0b ? sh_tran_cnt_in : // Transfer Count
bram_raddr_r == 8'h0c ? sh_autoact_in :
bram_raddr_r == 8'h0d ? sh_inter_in :
bram_raddr_r == 8'h0e ? sh_dir_in :
bram_raddr_r == 8'h0f ? cmd_in :
bram_raddr_r == 8'h10 ? sh_err_in :
bram_raddr_r == 8'h11 ? sh_status_in :
bram_raddr_r == 8'h12 ? sh_estatus_in : // E_Status
bram_raddr_r == 8'h13 ? sh_port_in :
bram_raddr_r == 8'h14 ? sh_dma_cnt_in :
bram_raddr_r == 8'h15 ? sh_notif_in :
32'hd34db33f;
end
assign bram_rdata = bram_rdata_r;
......
This diff is collapsed.
This diff is collapsed.
......@@ -26,7 +26,7 @@
// All references to doc = to SerialATA_Revision_2_6_Gold.pdf
module oob #(
parameter DATA_BYTE_WIDTH = 4,
parameter CLK_SPEED_GRADE = 2, // 1 - 75 Mhz, 2 - 150Mhz, 4 - 300Mhz
parameter CLK_SPEED_GRADE = 2 // 1 - 75 Mhz, 2 - 150Mhz, 4 - 300Mhz
)
(
// sata clk = usrclk2
......@@ -94,7 +94,7 @@ module oob #(
// reset speedgrade to the fastest one
output wire speed_rst_req,
input wire speed_rst_ack
`endif OOB_MULTISPEED
`endif //OOB_MULTISPEED
);
// 873.8 us error timer
......@@ -118,7 +118,7 @@ reg [DATA_BYTE_WIDTH - 1:0] rxcharisk;
// primitives detection
wire detected_alignp;
wire detected_synp;
wire detected_syncp;
// fsm, doc p265,266
wire state_idle;
......@@ -157,13 +157,13 @@ assign set_wait_cominit = state_idle & oob_start & ~cominit_req;
assign set_wait_comwake = state_idle & cominit_req & cominit_allow | state_wait_cominit & rxcominitdet;
assign set_wait_align = state_wait_comwake & rxcomwakedet;
assign set_wait_synp = state_wait_align & detected_alignp;
assign set_wait_linkup = state_wait_synp & detected_synp;
assign set_wait_linkup = state_wait_synp & detected_syncp;
assign set_error = timer_fin & (state_wait_cominit | state_wait_comwake | state_wait_align | state_wait_synp/* | state_wait_linkup*/);
assign clr_wait_cominit = set_wait_comwake | set_error;
assign clr_wait_comwake = set_wait_align | set_error;
assign clr_wait_align = set_wait_synp | set_error;
assign clr_wait_synp = set_wait_linkup | set_error;
assign clr_wait_linkup = state_linkup; //TODO not so important, but still have to trace 3 back-to-back non alignp primitives
assign clr_wait_linkup = state_wait_linkup; //TODO not so important, but still have to trace 3 back-to-back non alignp primitives
assign clr_error = state_error;
// waiting timeout timer
......@@ -179,7 +179,7 @@ assign oob_incompatible = state_wait_align & set_error;
assign oob_done = set_wait_linkup;
// noone responds to cominits
assign oob_silince = set_error & state_wait_cominit;
assign oob_silence = set_error & state_wait_cominit;
// other timeouts
assign oob_error = set_error & ~oob_silence & ~oob_incompatible;
......@@ -207,34 +207,40 @@ assign cominit_req = cominit_req_set | cominit_req_r;
// detect which primitives sends the device after comwake was done
generate
if (DATA_BYTE_WIDTH == 16)
if (DATA_BYTE_WIDTH == 2)
begin
reg detected_alignp_f;
always @ (posedge clk)
detected_alignp_f <= rst | ~state_wait_align ? 1'b0 :
~|(rxdata ^ {8'b01001010, 8'b10111100}) & ~|(rxchaisk ^ 2'b01); // {D10.2, K28.5}
assign detected_alignp = detected_aligp_f & ~|(rxdata ^ {8'b01111011, 8'b01001010}) & ~|(rxchaisk ^ 2'b00); // {D27.3, D10.2}
~|(rxdata ^ {8'b01001010, 8'b10111100}) & ~|(rxcharisk ^ 2'b01); // {D10.2, K28.5}
assign detected_alignp = detected_alignp_f & ~|(rxdata ^ {8'b01111011, 8'b01001010}) & ~|(rxcharisk ^ 2'b00); // {D27.3, D10.2}
reg detected_syncp_f;
always @ (posedge clk)
detected_syncp_f <= rst | ~state_wait_sync ? 1'b0 :
~|(rxdata ^ {8'b10010101, 8'b01111100}) & ~|(rxchaisk ^ 2'b01); // {D21.4, K28.3}
assign detected_syncp = detected_syncp_f & ~|(rxdata ^ {8'b10110101, 8'b10110101}) & ~|(rxchaisk ^ 2'b00); // {D21.5, D21.5}
detected_syncp_f <= rst | ~state_wait_synp ? 1'b0 :
~|(rxdata ^ {8'b10010101, 8'b01111100}) & ~|(rxcharisk ^ 2'b01); // {D21.4, K28.3}
assign detected_syncp = detected_syncp_f & ~|(rxdata ^ {8'b10110101, 8'b10110101}) & ~|(rxcharisk ^ 2'b00); // {D21.5, D21.5}
end
else
if (DATA_BYTE_WIDTH == 32)
if (DATA_BYTE_WIDTH == 4)
begin
assign detected_alignp = detected_aligp_f & ~|(rxdata ^ {8'b01111011, 8'b01001010, 8'b01001010, 8'b10111100}) & ~|(rxchaisk ^ 4'h1); // {D27.3, D10.2, D10.2, K28.5}
assign detected_syncp = detected_syncp_f & ~|(rxdata ^ {8'b10110101, 8'b10110101, 8'b10010101, 8'b01111100}) & ~|(rxchaisk ^ 4'h1); // {D21.5, D21.5, D21.4, K28.3}
assign detected_alignp = ~|(rxdata ^ {8'b01111011, 8'b01001010, 8'b01001010, 8'b10111100}) & ~|(rxcharisk ^ 4'h1); // {D27.3, D10.2, D10.2, K28.5}
assign detected_syncp = ~|(rxdata ^ {8'b10110101, 8'b10110101, 8'b10010101, 8'b01111100}) & ~|(rxcharisk ^ 4'h1); // {D21.5, D21.5, D21.4, K28.3}
end
else
if (DATA_BYTE_WIDTH == 64)
if (DATA_BYTE_WIDTH == 8)
begin
assign detected_alignp = detected_aligp_f & ~|(rxdata ^ {2{8'b01111011, 8'b01001010, 8'b01001010, 8'b10111100}}) & ~|(rxchaisk ^ 8'h11); // {D27.3, D10.2, D10.2, K28.5}
assign detected_syncp = detected_syncp_f & ~|(rxdata ^ {2{8'b10110101, 8'b10110101, 8'b10010101, 8'b01111100}}) & ~|(rxchaisk ^ 8'h11); // {D21.5, D21.5, D21.4, K28.3}
assign detected_alignp = ~|(rxdata ^ {2{8'b01111011, 8'b01001010, 8'b01001010, 8'b10111100}}) & ~|(rxcharisk ^ 8'h11); // {D27.3, D10.2, D10.2, K28.5}
assign detected_syncp = ~|(rxdata ^ {2{8'b10110101, 8'b10110101, 8'b10010101, 8'b01111100}}) & ~|(rxcharisk ^ 8'h11); // {D21.5, D21.5, D21.4, K28.3}
end
else
begin
always @ (posedge clk)
begin
$display("%m oob module works only with 16/32/64 gtx input data width");
$finish;
end
end
endgenerate
// buf inputs from gtx
......@@ -263,9 +269,9 @@ wire [DATA_BYTE_WIDTH - 1:0] txcharisk_align;
always @ (posedge clk)
begin
txdata <= state_wait_align ? txdata_d102 :
state_wait_sync ? txdata_align : txdata_in;
txchaisk <= state_wait_align ? txcharisk_d102 :
state_wait_sync ? txcharisk_align : txcharisk_in;
state_wait_synp ? txdata_align : txdata_in;
txcharisk <= state_wait_align ? txcharisk_d102 :
state_wait_synp ? txcharisk_align : txcharisk_in;
end
// Continious D10.2 primitive
......@@ -274,30 +280,34 @@ assign txdata_d102 = {DATA_BYTE_WIDTH{8'b01001010}};
// Align primitive: K28.5 + D10.2 + D10.2 + D27.3
generate
if (DATA_BYTE_WIDTH == 16)
if (DATA_BYTE_WIDTH == 2)
begin
reg align_odd;
always @ (posedge clk)
align_odd <= rst | ~state_wait_sync ? 1'b0 : ~align_odd;
align_odd <= rst | ~state_wait_synp ? 1'b0 : ~align_odd;
assign txcharisk_align = align_odd ? 2'b01 : 2'b00;
assign txdata_align = align_odd ? {8'b01001010, 8'b10111100} : // {D10.2, K28.5}
{8'b01111011, 8'b01001010); // {D27.3, D10.2}
{8'b01111011, 8'b01001010}; // {D27.3, D10.2}
end
else
if (DATA_BYTE_WIDTH == 32)
if (DATA_BYTE_WIDTH == 4)
begin
assign txcharisk_align = 4'h1;
assign txdata_align = {8'b01111011, 8'b01001010, 8'b01001010, 8'b10111100}; // {D27.3, D10.2, D10.2, K28.5}
end
else
if (DATA_BYTE_WIDTH == 64)
if (DATA_BYTE_WIDTH == 8)
begin
assign txcharisk_align = 8'h11;
assign txdata_align = {2{8'b01111011, 8'b01001010, 8'b01001010, 8'b10111100}}; // 2x{D27.3, D10.2, D10.2, K28.5}
end
else
always @ (posedge clk)
begin
$display("%m oob module works only with 16/32/64 gtx input data width");
$finish;
end
endgenerate
// set data outputs to gtx
......
This diff is collapsed.
This diff is collapsed.
......@@ -395,7 +395,7 @@ dma_adapter dma_adapter(
membridge /*#(
.MEMBRIDGE_ADDR (),
V .MEMBRIDGE_ADDR (),
.MEMBRIDGE_MASK (),
.MEMBRIDGE_CTRL (),
.MEMBRIDGE_STATUS_CNTRL (),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment