Commit 65abe0b4 authored by Alexey Grebenkin's avatar Alexey Grebenkin

connected sata host to system ifaces, phy is rewritten. Pre-testing rtl

parent 3153826e
......@@ -2,7 +2,7 @@
* Module: axi_regs
* Date: 2015-07-11
* Author: Alexey
* Description: temporary registers, connected to axi bus
* Description: slave axi interface buffer
*
* Copyright (c) 2015 Elphel, Inc.
* axi_regs.v is free software; you can redistribute it and/or modify
......@@ -18,33 +18,12 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
/*
* Some common formulas for AXI:
* // - integer division, % - leftover
* addr = raddr(waddr) % device_memory_size
* size = arsize(awsize), size_bytes = 2^size, bus_width = log2(bus_width_bytes),
* bus_offset = addr % bus_width_bytes, aligned_bus_addr - address of the first byte on a bus
* word_addr - current memory word's index, word_size_bytes - memory word size
* For the i-th byte on a bus,
* -------burst_cnt = 0:
* aligned_bus_addr = addr // bus_width_bytes * bus_width_bytes
* word_addr[i] = (aligned_bus_addr + i) // word_size_bytes
* word_data[i] = mem[word_addr[i]]
* >data[i] = word_data[i][i % word_size]
* >atrobe[i] = i[bus_width:size] == bus_offset[bus_width:size] & i[size-1:0] >= bus_offset[size-1:0]
* -------burst_cnt > 0:
* let addr_-1 be an addr of a last burst
* Incremental
* addr = addr_-1 // size_bytes * size_bytes + size_bytes
*
* Wrapping
* addr = addr_-1 // size_bytes * size_bytes + size_bytes
*/
`include "axibram_read.v"
`include "axibram_write.v"
`include "membridge.v"
module axi_regs(
module axi_regs #(
parameter REGISTERS_CNT = 20
)
(
input wire ACLK, // AXI PS Master GP1 Clock , input
input wire ARESETN, // AXI PS Master GP1 Reset, output
// AXI PS Master GP1: Read Address
......@@ -90,57 +69,19 @@ module axi_regs(
input wire BREADY, // AXI PS Master GP1 BREADY, output
output wire [11:0] BID, // AXI PS Master GP1 BID[11:0], input
output wire [1:0] BRESP, // AXI PS Master GP1 BRESP[1:0], input
// registers iface
input wire [31:0] bram_rdata,
output wire [31:0] bram_waddr,
output wire [31:0] bram_wdata,
output wire [31:0] bram_raddr,
output wire [3:0] bram_wstb,
output wire bram_wen,
output wire bram_ren,
output wire bram_regen
);
// register set
//reg [31:0] mem [3:0];
/*
* DMA write:
* 0x10: addr of the buffer
* 0x14: size
* 0x18: burst len
* 0x1c:
* 0x20-0x3c - data
* Converntional MAXI interface from x393 project
*/
reg [32*REGISTERS_CNT - 1:0] mem;
/*
* Converntional MAXI interface from x393 project, uses fifos, writes to/reads from memory
*/
wire [31:0] bram_waddr;
wire [31:0] bram_raddr;
wire [31:0] bram_wdata;
wire [31:0] bram_rdata;
wire [3:0] bram_wstb;
wire bram_wen;
wire bram_ren;
wire bram_regen;
// 'write into memory'
// for testing purposes the 'memory' is a set of registers for now
// later on will try to use them as an application level registers
genvar ii;
generate
for (ii = 0; ii < REGISTERS_CNT; ii = ii + 1)
begin: write_to_mem
always @ (posedge ACLK)
begin
mem[32*ii + 31-:8] <= bram_wen & (bram_waddr[3:0] == ii) ? bram_wdata[31-:8] & {8{bram_wstb[3]}}: mem[32*ii + 31-:8];
mem[32*ii + 23-:8] <= bram_wen & (bram_waddr[3:0] == ii) ? bram_wdata[23-:8] & {8{bram_wstb[2]}}: mem[32*ii + 23-:8];
mem[32*ii + 15-:8] <= bram_wen & (bram_waddr[3:0] == ii) ? bram_wdata[15-:8] & {8{bram_wstb[1]}}: mem[32*ii + 15-:8];
mem[32*ii + 7-:8] <= bram_wen & (bram_waddr[3:0] == ii) ? bram_wdata[ 7-:8] & {8{bram_wstb[0]}}: mem[32*ii + 7-:8];
end
end
endgenerate
// read from memory. Interface's protocol assumes returning data to delay
reg [3: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_rdata_r <= bram_regen ? mem[32*bram_raddr_r + 31-:32] : bram_rdata_r;
end
assign bram_rdata = bram_rdata_r;
// Interface's instantiation
axibram_write #(
.ADDRESS_BITS(16)
......
......@@ -129,11 +129,12 @@ reg rd_reset_page;
reg rd_next_page;
reg rd_data;
reg [6:0] rd_data_count;
reg rd_en;
wire rd_stop;
wire rd_cnt_to_pull;
assign rd_cnt_to_pull == 7'hf;
assign rd_cnt_to_pull = 7'hf;
assign rd_stop = rd_ack_in & rd_data_count == rd_cnt_to_pull;
assign rd_data_out = rd_data;
......@@ -148,39 +149,40 @@ always @ (posedge clk)
rd_en <= 1'b0;
end
else
case (rst)
READ_IDLE:
begin
rdwr_state <= rd_start ? READ_WAIT_ADDR : READ_IDLE;
rd_done <= 1'b0;
rd_data_count <= 7'h0;
rd_next_page <= 1'b0;
rd_en <= 1'b0;
end
READ_WAIT_ADDR: // wait until address information is sent to the bus and input buffer got data
begin
rdwr_state <= membr_state == IDLE & rdata_done ? READ_DATA : READ_WAIT_ADDR;
rd_done <= 1'b0;
rd_data_count <= 7'h0;
rd_next_page <= 1'b0;
rd_en <= 1'b0;
end
READ_DATA:
begin
rdwr_state <= rd_stop ? READ_IDLE : READ_DATA;
rd_done <= rd_stop ? 1'b1 : 1'b0;
rd_data_count <= rd_ack_in ? rd_data_count + 1'b1 : rd_data_count;
rd_next_page <= rd_stop ? 1'b1 : 1'b0;
rd_en <= rd_ack_in ? 1'b1 : 1'b0;
end
default: // write is processing
begin
rdwr_state <= READ_IDLE;
rd_done <= 1'b0;
rd_data_count <= 7'h0;
rd_next_page <= 1'b0;
rd_en <= 1'b0;
end
case (rdwr_state)
READ_IDLE:
begin
rdwr_state <= rd_start ? READ_WAIT_ADDR : READ_IDLE;
rd_done <= 1'b0;
rd_data_count <= 7'h0;
rd_next_page <= 1'b0;
rd_en <= 1'b0;
end
READ_WAIT_ADDR: // wait until address information is sent to the bus and input buffer got data
begin
rdwr_state <= membr_state == READ_IDLE & rdata_done ? READ_DATA : READ_WAIT_ADDR;
rd_done <= 1'b0;
rd_data_count <= 7'h0;
rd_next_page <= 1'b0;
rd_en <= 1'b0;
end
READ_DATA:
begin
rdwr_state <= rd_stop ? READ_IDLE : READ_DATA;
rd_done <= rd_stop ? 1'b1 : 1'b0;
rd_data_count <= rd_ack_in ? rd_data_count + 1'b1 : rd_data_count;
rd_next_page <= rd_stop ? 1'b1 : 1'b0;
rd_en <= rd_ack_in ? 1'b1 : 1'b0;
end
default: // write is processing
begin
rdwr_state <= READ_IDLE;
rd_done <= 1'b0;
rd_data_count <= 7'h0;
rd_next_page <= 1'b0;
rd_en <= 1'b0;
end
endcase
// Put data into buffer
......@@ -220,7 +222,7 @@ always @ (posedge clk)
rdwr_state <= WRITE_IDLE;
end
else
case (wr_state)
case (rdwr_state)
WRITE_IDLE:
begin
wr_data_count <= 7'd0;
......@@ -234,26 +236,26 @@ always @ (posedge clk)
end
WRITE_DATA:
begin
wr_done <= wr_stop & membr_state == IDLE ? 1'b1 : 1'b0;
wr_done <= wr_stop & membr_state == WRITE_IDLE ? 1'b1 : 1'b0;
wr_data_count <= wr_val_in ? wr_data_count + 1'b1 : wr_data_count;
wr_data <= in_data :
wr_data <= wr_data_in;
wr_next_page <= wr_stop ? 1'b1 : 1'b0;
wr_reset_page <= 1'b0;
wr_en <= wr_val_in;
wr_page_ready <= wr_stop ? 1'b1 : 1'b0;
rdwr_state <= wr_stop & membr_state == IDLE ? WRITE_IDLE :
rdwr_state <= wr_stop & membr_state == WRITE_IDLE ? WRITE_IDLE :
wr_stop ? WRITE_WAIT_ADDR : WRITE_DATA;
end
WRITE_WAIT_ADDR: // in case all data is written into a buffer, but address is still being issued on axi bus
begin
wr_done <= membr_state == IDLE ? 1'b1 : 1'b0;
wr_done <= membr_state == WRITE_IDLE ? 1'b1 : 1'b0;
wr_data_count <= 7'd0;
wr_data <= 64'h0;
wr_next_page <= 1'b0;
wr_reset_page <= 1'b0;
wr_en <= 1'b0;
wr_page_ready <= 1'b0;
rdwr_state <= membr_state == IDLE ? WRITE_IDLE : WRITE_WAIT_ADDR;
rdwr_state <= membr_state == WRITE_IDLE ? WRITE_IDLE : WRITE_WAIT_ADDR;
end
default: // read is executed
begin
......@@ -322,7 +324,7 @@ always @ (posedge clk)
membr_start <= dma_start ? 1'b1 : 1'b0;
membr_setup <= dma_start ? 1'b1 : 1'b0;
membr_done <= 1'b0;
membr_state <= dma_start & membr_is_set ? MEMBR_LOADDDR :
membr_state <= dma_start & membr_is_set ? MEMBR_LOADDR :
dma_start ? MEMBR_MODE : MEMBR_IDLE;
end
MEMBR_MODE:
......
......@@ -19,43 +19,207 @@
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
/*
* Later on most of address evaluation logic could divided into 2 parts, which
* Later on most of address evaluation logic could be divided into 2 parts, which
* could be presented as 2 instances of 1 parameterized module
* + split data and address parts. Didnt do that because not sure if
* virtual channels would be implemented in the future
*/
module dma_control(
input wire sclk, // sata clock
input wire hclk, // axi-hp clock
input wire rst,
// registers iface
input wire [31:7] mem_address,
input wire [31:0] lba,
input wire [31:0] sector_cnt,
input wire dma_type,
input wire dma_start,
output wire dma_done,
// adapter data iface
// to main memory
output wire [63:0] to_data,
output wire to_val,
input wire to_ack,
// from main memory
input wire [63:0] from_data,
input wire from_val,
input wire from_ack
// sata host iface
// data from sata host
input wire [31:0] in_data,
output wire in_val,
input wire in_busy,
// data to sata host
output wire [31:0] out_data,
output wire out_val,
input wire out_busy
);
module dma_control(
input wire sclk, // sata clock
input wire hclk, // axi-hp clock
input wire rst,
// registers iface
input wire [31:7] mem_address,
input wire [31:0] lba,
input wire [31:0] sector_cnt,
input wire dma_type,
input wire dma_start,
output wire dma_done,
// adapter command iface
input wire adp_busy,
output wire [31:7] adp_addr,
output wire adp_type,
output wire adp_val,
// sata host command iface
input wire host_ready_for_cmd,
output wire host_new_cmd,
output wire [1:0] host_cmd_type,
output wire [31:0] host_sector_count,
output wire [31:0] host_sector_addr,
// adapter data iface
// to main memory
output wire [63:0] to_data,
output wire to_val,
input wire to_ack,
// from main memory
input wire [63:0] from_data,
input wire from_val,
output wire from_ack,
// sata host iface
// data from sata host
input wire [31:0] in_data,
output wire in_val,
input wire in_busy,
// data to sata host
output wire [31:0] out_data,
output wire out_val,
input wire out_busy
);
//////////////////////////////////////////////////////////////////////////////////////
//// ADDRESS
//////////////////////////////////////////////////////////////////////////////////////
wire dma_done_adp;
wire dma_done_host;
assign dma_done = dma_done_host & dma_done_adp;
reg adp_busy_sclk;
/*
* Commands to sata host fsm
*/
// for now only 2 states: idle and send a pulse
reg host_issued;
wire host_issued_set;
wire host_issued_clr;
assign dma_done_host = host_issued;
assign host_issued_set = ~adp_busy_sclk & host_ready_for_cmd & dma_start;
assign host_issued_clr = dma_done;
always @ (posedge sclk)
host_issued <= (host_issued | host_issued_set) & ~host_issued_clr & ~rst;
// drive iface signals
assign host_new_cmd = host_issued_set;
assign host_cmd_type = dma_type;
assign host_sector_count = sector_cnt;
assign host_sector_addr = lba;
/*
* Commands to adapter fsm
*/
reg [33:0] quarter_sector_cnt;
wire last_data; // last 128 bytes of data are transmitted now
wire adp_val_sclk;
reg [31:7] current_addr;
reg current_type;
// synchronize with host fsm
reg adp_done;
wire adp_done_clr;
wire adp_done_set;
assign dma_done_adp = adp_done;
assign adp_done_set = state_wait_done & clr_wait_done & ~set_wait_busy; // = state_wait_done & set_idle;
assign adp_done_clr = dma_done;
always @ (posedge sclk)
adp_done <= (adp_done | adp_done_set) & ~adp_done_clr & ~rst;
// calculate sent sector count
// 1 sector = 512 bytes for now => 1 quarter_sector = 128 bytes
always @ (posedge sclk)
quarter_sector_cnt <= ~set_wait_busy ? quarter_sector_cnt :
state_idle ? 34'h0 : // new dma request
quarter_sector_cnt + 1'b1; // same dma request, next 128 bytes
// flags if we're currently sending the last data piece of dma transaction
assign last_data = (sector_cnt == quarter_sector_cnt[33:2] + 1'b1) & (&quarter_sector_cnt[1:0]);
// calculate outgoing address
// increment every transaction to adapter
always @ (posedge sclk)
current_addr <= ~set_wait_busy ? current_addr :
state_idle ? mem_address : // new dma request
current_addr + 1'b1; // same dma request, next 128 bytes
always @ (posedge sclk)
current_type <= ~set_wait_busy ? current_type :
state_idle ? dma_type : // new dma request
current_type; // same dma request, next 128 bytes
// fsm itself
wire state_idle;
reg state_wait_busy;
reg state_wait_done;
wire set_wait_busy;
wire set_wait_done;
wire clr_wait_busy;
wire clr_wait_done;
assign set_wait_busy = state_idle & host_issued_set // same start pulse for both fsms
| state_wait_done & clr_wait_done & ~last_data; // still have some data to transmit within a current dma request
assign set_wait_done = state_wait_busy & clr_wait_busy;
assign clr_wait_busy = adp_busy_sclk;
assign clr_wait_done = ~adp_busy_sclk;
assign state_idle = ~state_wait_busy & ~state_wait_done;
always @ (posedge sclk)
begin
state_wait_busy <= (state_wait_busy | set_wait_busy) & ~clr_wait_busy & ~rst;
state_wait_done <= (state_wait_done | set_wait_done) & ~clr_wait_done & ~rst;
end
// conrol signals resync
reg adp_val_r;
reg adp_val_rr;
always @ (posedge hclk)
begin
adp_val_r <= adp_val_sclk;
adp_val_rr <= adp_val_r;
end
assign adp_addr = current_addr;
assign adp_type = current_type;
assign adp_val = adp_val_rr;
// Maintaining correct adp_busy level @ sclk
// assuming busy won't toggle rapidly, can afford not implementing handshakes
wire adp_busy_sclk_set;
wire adp_busy_sclk_clr;
wire adp_busy_set;
wire adp_busy_clr;
reg adp_busy_r;
assign adp_busy_set = adp_busy & ~adp_busy_r;
assign adp_busy_clr = ~adp_busy & adp_busy_r;
always @ (posedge sclk)
adp_busy_sclk <= (adp_busy_sclk | adp_busy_sclk_set) & ~rst & ~adp_busy_sclk_clr;
always @ (posedge hclk)
adp_busy_r <= adp_busy;
pulse_cross_clock adp_busy_set_pulse(
.rst (rst),
.src_clk (hclk),
.dst_clk (sclk),
.in_pulse (adp_busy_set),
.out_pulse (adp_busy_sclk_set),
.busy ()
);
pulse_cross_clock adp_busy_clr_pulse(
.rst (rst),
.src_clk (hclk),
.dst_clk (sclk),
.in_pulse (adp_busy_clr),
.out_pulse (adp_busy_sclk_clr),
.busy ()
);
//////////////////////////////////////////////////////////////////////////////////////
//// DATA
//////////////////////////////////////////////////////////////////////////////////////
/*
* from main memory resyncronisation circuit
*/
......@@ -65,8 +229,8 @@ reg [8:0] from_wr_addr;
wire [8:0] from_wr_next_addr;
wire [9:0] from_rd_next_addr;
// gray coded addresses
reg [9:0] from_rd_addr;
reg [8:0] from_wr_addr;
reg [9:0] from_rd_addr_gr;
reg [8:0] from_wr_addr_gr;
// anti-metastability shift registers for gray-coded addresses
reg [9:0] from_rd_addr_gr_r;
reg [8:0] from_wr_addr_gr_r;
......@@ -99,13 +263,13 @@ end
always @ (posedge sclk)
begin
from_wr_addr_gr_r <= rst ? 9'h0 : from_wr_addr;
from_wr_addr_gr_rr <= rst ? 9'h0 : from_wr_addr_rr;
from_wr_addr_gr_rr <= rst ? 9'h0 : from_wr_addr_gr_r;
end
// read address -> hclk (wr) domain to compare
always @ (posedge hclk)
begin
from_rd_addr_gr_r <= rst ? 10'h0 : from_rd_addr;
from_rd_addr_gr_rr <= rst ? 10'h0 : from_rd_addr_rr;
from_rd_addr_gr_rr <= rst ? 10'h0 : from_rd_addr_gr_r;
end
// translate resynced write address into ordinary (non-gray) address
genvar ii;
......@@ -169,8 +333,8 @@ reg [9:0] to_wr_addr;
wire [9:0] to_wr_next_addr;
wire [8:0] to_rd_next_addr;
// gray coded addresses
reg [8:0] to_rd_addr;
reg [9:0] to_wr_addr;
reg [8:0] to_rd_addr_gr;
reg [9:0] to_wr_addr_gr;
// anti-metastability shift registers for gray-coded addresses
reg [8:0] to_rd_addr_gr_r;
reg [9:0] to_wr_addr_gr_r;
......@@ -204,16 +368,15 @@ end
always @ (posedge hclk)
begin
to_wr_addr_gr_r <= rst ? 10'h0 : to_wr_addr;
to_wr_addr_gr_rr <= rst ? 10'h0 : to_wr_addr_rr;
to_wr_addr_gr_rr <= rst ? 10'h0 : to_wr_addr_gr_r;
end
// read address -> sclk (wr) domain to compare
always @ (posedge sclk)
begin
to_rd_addr_gr_r <= rst ? 9'h0 : to_rd_addr;
to_rd_addr_gr_rr <= rst ? 9'h0 : to_rd_addr_rr;
to_rd_addr_gr_rr <= rst ? 9'h0 : to_rd_addr_gr_r;
end
// translate resynced write address into ordinary (non-gray) address
genvar ii;
generate
for (ii = 0; ii < 10; ii = ii + 1)
begin: to_wr_antigray
......
/*******************************************************************************
* Module: dma_regs
* Date: 2015-07-11
* Author: Alexey
* Description: temporary registers, connected to axi bus
*
* Copyright (c) 2015 Elphel, Inc.
* dma_regs.v 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.
*
* dma_regs.v 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/> .
*******************************************************************************/
module dma_regs #(
parameter REGISTERS_CNT = 20
)
(
input wire rst,
input wire ACLK,
input wire sclk,
// registers iface
output wire [31:7] mem_address,
output wire [31:0] lba,
output wire [31:0] sector_cnt,
output wire dma_type,
output wire dma_start,
input wire dma_done,
// axi buffer iface
output wire [31:0] bram_rdata,
input wire [31:0] bram_raddr,
input wire [31:0] bram_waddr,
input wire [31:0] bram_wdata,
input wire [3:0] bram_wstb,
input wire bram_wen,
input wire bram_ren,
input wire bram_regen
);
//reg [32*REGISTERS_CNT - 1:0] mem;
/*
* Converntional MAXI interface from x393 project, uses fifos, writes to/reads from memory
*/
/*
* Temporary mapping:
* rw 0x00: dma address (will automatically align to 128-bytes boundary, i.e. [6:0] -> 0
* rw 0x04: lba
* rw 0x08: sector count
* rw 0x0c: dma type (any(0x0c) => write)
* r1c 0x10: writes: dma start (any(0x10) => start)
* reads: dma status of last issued transfer (0xffffffff => done)
* ro 0x14: dma last issued dma_address
*/
reg [31:0] reg00;
reg [31:0] reg04;
reg [31:0] reg08;
reg [31:0] reg0c;
reg [31:0] reg10;
reg [31:0] reg14;
wire dma_done_aclk;
wire dma_start_aclk;
reg dma_issued;
wire [31:0] wdata;
pulse_cross_clock dma_done_pulse(
.rst (rst),
.src_clk (sclk),
.dst_clk (ACLK),
.in_pulse (dma_done),
.out_pulse (dma_done_aclk),
.busy ()
);
pulse_cross_clock dma_start_pulse(
.rst (rst),
.src_clk (ACLK),
.dst_clk (sclk),
.in_pulse (dma_start_aclk & ~dma_issued),
.out_pulse (dma_start),
.busy ()
);
assign dma_start_aclk = bram_wen & (bram_waddr[3:0] == 4'h4) & |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)
dma_issued <= (dma_issued | dma_start_aclk) & ~rst & ~dma_done_aclk;
assign mem_address = reg00[31:7];
assign lba = reg04;
assign sector_cnt = reg08;
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;
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
// read from registers. Interface's protocol assumes returning data with a delay
reg [3: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_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 :
32'hd34db33f;
end
assign bram_rdata = bram_rdata_r;
/*
// for testing purposes the 'memory' is a set of registers for now
// later on will try to use them as an application level registers
genvar ii;
generate
for (ii = 0; ii < REGISTERS_CNT; ii = ii + 1)
begin: write_to_mem
always @ (posedge ACLK)
begin
mem[32*ii + 31-:8] <= bram_wen & (bram_waddr[3:0] == ii) ? bram_wdata[31-:8] & {8{bram_wstb[3]}}: mem[32*ii + 31-:8];
mem[32*ii + 23-:8] <= bram_wen & (bram_waddr[3:0] == ii) ? bram_wdata[23-:8] & {8{bram_wstb[2]}}: mem[32*ii + 23-:8];
mem[32*ii + 15-:8] <= bram_wen & (bram_waddr[3:0] == ii) ? bram_wdata[15-:8] & {8{bram_wstb[1]}}: mem[32*ii + 15-:8];
mem[32*ii + 7-:8] <= bram_wen & (bram_waddr[3:0] == ii) ? bram_wdata[ 7-:8] & {8{bram_wstb[0]}}: mem[32*ii + 7-:8];
end
end
endgenerate
// read from memory. Interface's protocol assumes returning data with a delay
reg [3: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_rdata_r <= bram_regen ? mem[32*bram_raddr_r + 31-:32] : bram_rdata_r;
end
assign bram_rdata = bram_rdata_r;
*/
endmodule
......@@ -40,7 +40,7 @@ module sata_host(
input wire data_clk_out,
// timer
output wire sata_timer,
output wire [31:0] sata_timer,
// phy
input wire clkin_150,
......@@ -50,9 +50,47 @@ module sata_host(
output wire txp_out,
output wire txn_out,
input wire rxp_in,
input wire rxn_in
);
input wire rxn_in,
output wire plllkdet,
output wire dcmlocked
);/*
assign ready_for_cmd = 1'b0;
assign sata_core_full = 1'b0;
assign sata_dout = 32'b0;
assign sata_core_empty = 1'b0;
assign sata_timer = 1'b0;
assign linkup = 1'b0;
assign txp_out = 1'b0;
assign txn_out = 1'b0;
assign plllkdet = 1'b0;
assign dcmlocked = 1'b0;*/
sata_core sata_core(
.ready_for_cmd (ready_for_cmd),
.new_cmd (new_cmd),
.cmd_type (cmd_type),
.sector_count (sector_count),
.sector_addr (sector_addr),
.sata_din (sata_din),
.sata_din_we (sata_din_we),
.sata_core_full (sata_core_full),
.sata_dout (sata_dout),
.sata_dout_re (sata_dout_re),
.sata_core_empty (sata_core_empty),
.SATA_USER_DATA_CLK_IN (data_clk_in),
.SATA_USER_DATA_CLK_OUT (data_clk_out),
.sata_timer (sata_timer),
.CLKIN_150 (clkin_150),
.reset (reset),
.LINKUP (linkup),
.TXP0_OUT (txp_out),
.TXN0_OUT (txn_out),
.RXP0_IN (rxp_in),
.RXN0_IN (rxn_in),
.PLLLKDET_OUT_N (plllkdet),
.DCMLOCKED_OUT (dcmlocked)
);
endmodule
/*******************************************************************************
* Module: sata_phy
* Date: 2015-07-11
* Author: Alexey
* Description: Ashwin's sata_phy replacement with 7-series support
*
* Copyright (c) 2015 Elphel, Inc.
* sata_phy.v 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.
*
* sata_phy.v 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/> .
*******************************************************************************/
module sata_phy(
input wire REFCLK_PAD_P_IN, // GTX reference clock input
input wire REFCLK_PAD_N_IN, // GTX reference clock input
input wire RXP0_IN, // Receiver input
input wire RXN0_IN, // Receiver input
input wire GTXRESET_IN, // Main GTX reset
input wire CLKIN_150, // reliable clock input
// Input from Link Layer
input wire [31:0] tx_datain,
input wire tx_charisk_in,
output wire DCMLOCKED_OUT, // DCM locked
output wire PLLLKDET_OUT_N, // PLL Lock Detect
output wire TXP0_OUT,
output wire TXN0_OUT,
output wire LINKUP,
output wire LINKUP_led,
output wire GEN2_led,
output wire align_en_out,
output wire sata_user_clk,
// Outputs to Link Layer
output wire [31:0] rx_dataout,
output wire [3:0] rx_charisk_out,
output wire [7:0] CurrentState_out,
output wire rxelecidle_out,
// Rudiments
input wire [35:0] sata_phy_ila_control,
input wire [35:0] oob_control_ila_control
);
parameter CHIPSCOPE = "FALSE";
wire [31:0] txdata;
wire txcharisk;
wire [63:0] rxdata;
wire [7:0] rxcharisk;
wire [31:0] rxdata_out;
wire [3:0] rxcharisk_out;
wire linkup;
wire linkup_led;
wire rxcomwakedet;
wire rxcominitdet;
wire cplllock;
wire txcominit;
wire txcomwake;
wire rxreset;
wire rxelecidle;
wire txelecidle;
wire rxbyteisaligned;
OOB_control oob_control(
.oob_control_ila_control (36'h0),
//-------- GTX Ports --------/
.clk (sata_user_clk),
.reset (GTXRESET_IN),
.rxreset (/*rxreset*/),
.rx_locked (cplllock),
// OOB generation and detection signals from GTX
.txcominit (txcominit),
.txcomwake (txcomwake),
.cominitdet (rxcominitdet),
.comwakedet (rxcomwakedet),
.rxelecidle (rxelecidle),
.txelecidle_out (txelecidle),
.rxbyteisaligned (rxbyteisaligned),
.tx_dataout (txdata), // outgoing GTX data
.tx_charisk_out (txcharisk), // GTX charisk out
.rx_datain (rxdata[31:0]), // incoming GTX data
.rx_charisk_in (rxcharisk[3:0]), // GTX charisk in
.gen2 (1'b1), // for SATA Generation 2
//----- USER DATA PORTS---------//
.tx_datain (tx_datain), // User datain port
.tx_charisk_in (tx_charisk_in), // User charisk in port
.rx_dataout (rxdata_out), // User dataout port
.rx_charisk_out (rxcharisk_out), // User charisk out port
.linkup (linkup),
.linkup_led_out (linkup_led),
.align_en_out (align_en_out),
.CurrentState_out (CurrentState_out)
);
wire cplllockdetclk; // TODO
wire drpclk; // TODO
wire cpllreset;
wire gtrefclk;
wire rxresetdone;
wire txresetdone;
wire txreset;
wire txuserrdy;
wire rxuserrdy;
wire txusrclk;
wire txusrclk2;
wire rxusrclk;
wire rxusrclk2;
wire txp;
wire txn;
wire rxp;
wire rxn;
wire txoutclk;
wire txpmareset_done;
wire rxeyereset_done;
// tx reset sequence; waves @ ug476 p67
localparam TXPMARESET_TIME = 5'h1;
reg [2:0] txpmareset_cnt;
assign txpmareset_done = txpmareset_cnt == TXPMARESET_TIME;
always @ (posedge gtrefclk)
txpmareset_cnt <= txreset ? 3'h0 : txpmareset_done ? txpmareset_cnt : txpmareset_cnt + 1'b1;
// rx reset sequence; waves @ ug476 p77
localparam RXPMARESET_TIME = 5'h11;
localparam RXCDRPHRESET_TIME = 5'h1;
localparam RXCDRFREQRESET_TIME = 5'h1;
localparam RXDFELPMRESET_TIME = 7'hf;
localparam RXISCANRESET_TIME = 5'h1;
localparam RXEYERESET_TIME = 7'h0 + RXPMARESET_TIME + RXCDRPHRESET_TIME + RXCDRFREQRESET_TIME + RXDFELPMRESET_TIME + RXISCANRESET_TIME;
reg [6:0] rxeyereset_cnt;
assign rxeyereset_done = rxeyereset_cnt == RXEYERESET_TIME;
always @ (posedge gtrefclk)
rxeyereset_cnt <= rxreset ? 3'h0 : rxeyereset_done ? rxeyereset_cnt : rxeyereset_cnt + 1'b1;
/*
* Resets
*/
wire usrpll_locked;
assign cpllreset = GTXRESET_IN;
assign rxreset = ~cplllock | cpllreset;
assign txreset = ~cplllock | cpllreset;
assign rxuserrdy = usrpll_locked & cplllock & ~cpllreset & ~rxreset & rxeyereset_done;
assign txuserrdy = usrpll_locked & cplllock & ~cpllreset & ~txreset & txpmareset_done;
/*
* USRCLKs generation. USRCLK @ 150MHz, same as TXOUTCLK; USRCLK2 @ 75Mhz -> sata_clk === sclk
* It's recommended to use MMCM instead of PLL, whatever
*/
wire usrpll_fb_clk;
wire usrclk;
wire usrclk2;
assign txusrclk = usrclk;
assign txusrclk2 = usrclk2;
assign rxusrclk = usrclk;
assign rxusrclk2 = usrclk2;
PLLE2_ADV #(
.BANDWIDTH ("OPTIMIZED"),
.CLKFBOUT_MULT (8),
.CLKFBOUT_PHASE (0.000),
.CLKIN1_PERIOD (6.666),
.CLKIN2_PERIOD (0.000),
.CLKOUT0_DIVIDE (8),
.CLKOUT0_DUTY_CYCLE (0.500),
.CLKOUT0_PHASE (0.000),
.CLKOUT1_DIVIDE (16),
.CLKOUT1_DUTY_CYCLE (0.500),
.CLKOUT1_PHASE (0.000),
/* .CLKOUT2_DIVIDE = 1,
.CLKOUT2_DUTY_CYCLE = 0.500,
.CLKOUT2_PHASE = 0.000,
.CLKOUT3_DIVIDE = 1,
.CLKOUT3_DUTY_CYCLE = 0.500,
.CLKOUT3_PHASE = 0.000,
.CLKOUT4_DIVIDE = 1,
.CLKOUT4_DUTY_CYCLE = 0.500,
.CLKOUT4_PHASE = 0.000,
.CLKOUT5_DIVIDE = 1,
.CLKOUT5_DUTY_CYCLE = 0.500,
.CLKOUT5_PHASE = 0.000,*/
.COMPENSATION ("ZHOLD"),
.DIVCLK_DIVIDE (1),
.IS_CLKINSEL_INVERTED (1'b0),
.IS_PWRDWN_INVERTED (1'b0),
.IS_RST_INVERTED (1'b0),
.REF_JITTER1 (0.010),
.REF_JITTER2 (0.010),
.STARTUP_WAIT ("FALSE")
)
usrclk_pll(
.CLKFBOUT (usrpll_fb_clk),
.CLKOUT0 (usrclk),
.CLKOUT1 (usrclk2),
.CLKOUT2 (),
.CLKOUT3 (),
.CLKOUT4 (),
.CLKOUT5 (),
.DO (),
.DRDY (),
.LOCKED (usrpll_locked),
.CLKFBIN (usrpll_fb_clk),
.CLKIN1 (txoutclk),
.CLKIN2 (1'b0),
.CLKINSEL (1'b1),
.DADDR (7'h0),
.DCLK (drpclk),
.DEN (1'b0),
.DI (16'h0),
.DWE (1'b0),
.PWRDWN (1'b0),
.RST (~cplllock)
);
/*
* Padding for an external input clock @ 150 MHz
* TODO !!! Temporary moved to sata_top
*/
assign gtrefclk = CLKIN_150;
/*localparam [1:0] CLKSWING_CFG = 2'b11;
IBUFDS_GTE2 #(
.CLKRCV_TRST ("TRUE"),
.CLKCM_CFG ("TRUE"),
.CLKSWING_CFG (CLKSWING_CFG)
)
ext_clock_buf(
.I (REFCLK_PAD_P_IN),
.IB (REFCLK_PAD_N_IN),
.CEB (1'b0),
.O (gtrefclk),
.ODIV2 ()
);
*/
GTXE2_CHANNEL #(
.SIM_RECEIVER_DETECT_PASS ("TRUE"),
.SIM_TX_EIDLE_DRIVE_LEVEL ("X"),
.SIM_RESET_SPEEDUP ("FALSE"),
.SIM_CPLLREFCLK_SEL (3'b001),
.SIM_VERSION ("4.0"),
.ALIGN_COMMA_DOUBLE ("FALSE"),
.ALIGN_COMMA_ENABLE (10'b1111111111),
.ALIGN_COMMA_WORD (1),
.ALIGN_MCOMMA_DET ("TRUE"),
.ALIGN_MCOMMA_VALUE (10'b1010000011),
.ALIGN_PCOMMA_DET ("TRUE"),
.ALIGN_PCOMMA_VALUE (10'b0101111100),
.SHOW_REALIGN_COMMA ("TRUE"),
.RXSLIDE_AUTO_WAIT (7),
.RXSLIDE_MODE ("OFF"),
.RX_SIG_VALID_DLY (10),
.RX_DISPERR_SEQ_MATCH ("TRUE"),
.DEC_MCOMMA_DETECT ("TRUE"),
.DEC_PCOMMA_DETECT ("TRUE"),
.DEC_VALID_COMMA_ONLY ("FALSE"),
.CBCC_DATA_SOURCE_SEL ("DECODED"),
.CLK_COR_SEQ_2_USE ("FALSE"),
.CLK_COR_KEEP_IDLE ("FALSE"),
.CLK_COR_MAX_LAT (9),
.CLK_COR_MIN_LAT (7),
.CLK_COR_PRECEDENCE ("TRUE"),
.CLK_COR_REPEAT_WAIT (0),
.CLK_COR_SEQ_LEN (1),
.CLK_COR_SEQ_1_ENABLE (4'b1111),
.CLK_COR_SEQ_1_1 (10'b0100000000),
.CLK_COR_SEQ_1_2 (10'b0000000000),
.CLK_COR_SEQ_1_3 (10'b0000000000),
.CLK_COR_SEQ_1_4 (10'b0000000000),
.CLK_CORRECT_USE ("FALSE"),
.CLK_COR_SEQ_2_ENABLE (4'b1111),
.CLK_COR_SEQ_2_1 (10'b0100000000),
.CLK_COR_SEQ_2_2 (10'b0000000000),
.CLK_COR_SEQ_2_3 (10'b0000000000),
.CLK_COR_SEQ_2_4 (10'b0000000000),
.CHAN_BOND_KEEP_ALIGN ("FALSE"),
.CHAN_BOND_MAX_SKEW (1),
.CHAN_BOND_SEQ_LEN (1),
.CHAN_BOND_SEQ_1_1 (10'b0000000000),
.CHAN_BOND_SEQ_1_2 (10'b0000000000),
.CHAN_BOND_SEQ_1_3 (10'b0000000000),
.CHAN_BOND_SEQ_1_4 (10'b0000000000),
.CHAN_BOND_SEQ_1_ENABLE (4'b1111),
.CHAN_BOND_SEQ_2_1 (10'b0000000000),
.CHAN_BOND_SEQ_2_2 (10'b0000000000),
.CHAN_BOND_SEQ_2_3 (10'b0000000000),
.CHAN_BOND_SEQ_2_4 (10'b0000000000),
.CHAN_BOND_SEQ_2_ENABLE (4'b1111),
.CHAN_BOND_SEQ_2_USE ("FALSE"),
.FTS_DESKEW_SEQ_ENABLE (4'b1111),
.FTS_LANE_DESKEW_CFG (4'b1111),
.FTS_LANE_DESKEW_EN ("FALSE"),
.ES_CONTROL (6'b000000),
.ES_ERRDET_EN ("FALSE"),
.ES_EYE_SCAN_EN ("TRUE"),
.ES_HORZ_OFFSET (12'h000),
.ES_PMA_CFG (10'b0000000000),
.ES_PRESCALE (5'b00000),
.ES_QUALIFIER (80'h00000000000000000000),
.ES_QUAL_MASK (80'h00000000000000000000),
.ES_SDATA_MASK (80'h00000000000000000000),
.ES_VERT_OFFSET (9'b000000000),
.RX_DATA_WIDTH (20),
.OUTREFCLK_SEL_INV (2'b11),
.PMA_RSV (32'h00018480),
.PMA_RSV2 (16'h2050),
.PMA_RSV3 (2'b00),
.PMA_RSV4 (32'h00000000),
.RX_BIAS_CFG (12'b000000000100),
.DMONITOR_CFG (24'h000A00),
.RX_CM_SEL (2'b11),
.RX_CM_TRIM (3'b010),
.RX_DEBUG_CFG (12'b000000000000),
.RX_OS_CFG (13'b0000010000000),
.TERM_RCAL_CFG (5'b10000),
.TERM_RCAL_OVRD (1'b0),
.TST_RSV (32'h00000000),
.RX_CLK25_DIV (6),
.TX_CLK25_DIV (6),
.UCODEER_CLR (1'b0),
.PCS_PCIE_EN ("FALSE"),
.PCS_RSVD_ATTR (48'h0100),
.RXBUF_ADDR_MODE ("FAST"),
.RXBUF_EIDLE_HI_CNT (4'b1000),
.RXBUF_EIDLE_LO_CNT (4'b0000),
.RXBUF_EN ("TRUE"),
.RX_BUFFER_CFG (6'b000000),
.RXBUF_RESET_ON_CB_CHANGE ("TRUE"),
.RXBUF_RESET_ON_COMMAALIGN ("FALSE"),
.RXBUF_RESET_ON_EIDLE ("FALSE"),
.RXBUF_RESET_ON_RATE_CHANGE ("TRUE"),
.RXBUFRESET_TIME (5'b00001),
.RXBUF_THRESH_OVFLW (61),
.RXBUF_THRESH_OVRD ("FALSE"),
.RXBUF_THRESH_UNDFLW (4),
.RXDLY_CFG (16'h001F),
.RXDLY_LCFG (9'h030),
.RXDLY_TAP_CFG (16'h0000),
.RXPH_CFG (24'h000000),
.RXPHDLY_CFG (24'h084020),
.RXPH_MONITOR_SEL (5'b00000),
.RX_XCLK_SEL ("RXREC"),
.RX_DDI_SEL (6'b000000),
.RX_DEFER_RESET_BUF_EN ("TRUE"),
.RXCDR_CFG (72'h03000023ff10200020),
.RXCDR_FR_RESET_ON_EIDLE (1'b0),
.RXCDR_HOLD_DURING_EIDLE (1'b0),
.RXCDR_PH_RESET_ON_EIDLE (1'b0),
.RXCDR_LOCK_CFG (6'b010101),
.RXCDRFREQRESET_TIME (RXCDRFREQRESET_TIME),
.RXCDRPHRESET_TIME (RXCDRPHRESET_TIME),
.RXISCANRESET_TIME (RXISCANRESET_TIME),
.RXPCSRESET_TIME (5'b00001),
.RXPMARESET_TIME (RXPMARESET_TIME),
.RXOOB_CFG (7'b0000110),
.RXGEARBOX_EN ("FALSE"),
.GEARBOX_MODE (3'b000),
.RXPRBS_ERR_LOOPBACK (1'b0),
.PD_TRANS_TIME_FROM_P2 (12'h03c),
.PD_TRANS_TIME_NONE_P2 (8'h3c),
.PD_TRANS_TIME_TO_P2 (8'h64),
.SAS_MAX_COM (64),
.SAS_MIN_COM (36),
.SATA_BURST_SEQ_LEN (4'b0111),
.SATA_BURST_VAL (3'b110),
.SATA_EIDLE_VAL (3'b110),
.SATA_MAX_BURST (8),
.SATA_MAX_INIT (21),
.SATA_MAX_WAKE (7),
.SATA_MIN_BURST (4),
.SATA_MIN_INIT (12),
.SATA_MIN_WAKE (4),
.TRANS_TIME_RATE (8'h0E),
.TXBUF_EN ("TRUE"),
.TXBUF_RESET_ON_RATE_CHANGE ("TRUE"),
.TXDLY_CFG (16'h001F),
.TXDLY_LCFG (9'h030),
.TXDLY_TAP_CFG (16'h0000),
.TXPH_CFG (16'h0780),
.TXPHDLY_CFG (24'h084020),
.TXPH_MONITOR_SEL (5'b00000),
.TX_XCLK_SEL ("TXOUT"),
.TX_DATA_WIDTH (40),
.TX_DEEMPH0 (5'b00000),
.TX_DEEMPH1 (5'b00000),
.TX_EIDLE_ASSERT_DELAY (3'b110),
.TX_EIDLE_DEASSERT_DELAY (3'b100),
.TX_LOOPBACK_DRIVE_HIZ ("FALSE"),
.TX_MAINCURSOR_SEL (1'b0),
.TX_DRIVE_MODE ("DIRECT"),
.TX_MARGIN_FULL_0 (7'b1001110),
.TX_MARGIN_FULL_1 (7'b1001001),
.TX_MARGIN_FULL_2 (7'b1000101),
.TX_MARGIN_FULL_3 (7'b1000010),
.TX_MARGIN_FULL_4 (7'b1000000),
.TX_MARGIN_LOW_0 (7'b1000110),
.TX_MARGIN_LOW_1 (7'b1000100),
.TX_MARGIN_LOW_2 (7'b1000010),
.TX_MARGIN_LOW_3 (7'b1000000),
.TX_MARGIN_LOW_4 (7'b1000000),
.TXGEARBOX_EN ("FALSE"),
.TXPCSRESET_TIME (5'b00001),
.TXPMARESET_TIME (TXPMARESET_TIME),
.TX_RXDETECT_CFG (14'h1832),
.TX_RXDETECT_REF (3'b100),
.CPLL_CFG (24'hBC07DC),
.CPLL_FBDIV (4),
.CPLL_FBDIV_45 (5),
.CPLL_INIT_CFG (24'h00001E),
.CPLL_LOCK_CFG (16'h01E8),
.CPLL_REFCLK_DIV (1),
.RXOUT_DIV (2),
.TXOUT_DIV (2),
.SATA_CPLL_CFG ("VCO_3000MHZ"),
.RXDFELPMRESET_TIME (RXDFELPMRESET_TIME),
.RXLPM_HF_CFG (14'b00000011110000),
.RXLPM_LF_CFG (14'b00000011110000),
.RX_DFE_GAIN_CFG (23'h020FEA),
.RX_DFE_H2_CFG (12'b000000000000),
.RX_DFE_H3_CFG (12'b000001000000),
.RX_DFE_H4_CFG (11'b00011110000),
.RX_DFE_H5_CFG (11'b00011100000),
.RX_DFE_KL_CFG (13'b0000011111110),
.RX_DFE_LPM_CFG (16'h0954),
.RX_DFE_LPM_HOLD_DURING_EIDLE (1'b0),
.RX_DFE_UT_CFG (17'b10001111000000000),
.RX_DFE_VP_CFG (17'b00011111100000011),
.RX_CLKMUX_PD (1'b1),
.TX_CLKMUX_PD (1'b1),
.RX_INT_DATAWIDTH (0),
.TX_INT_DATAWIDTH (0),
.TX_QPI_STATUS_EN (1'b0),
.RX_DFE_KL_CFG2 (32'h301148AC),
.RX_DFE_XYD_CFG (13'b0000000000000),
.TX_PREDRIVER_MODE (1'b0)
)
dut(
.CPLLFBCLKLOST (),
.CPLLLOCK (cplllock),
.CPLLLOCKDETCLK (cplllockdetclk),
.CPLLLOCKEN (1'b1),
.CPLLPD (1'b0),
.CPLLREFCLKLOST (),
.CPLLREFCLKSEL (3'b001),
.CPLLRESET (cpllreset),
.GTRSVD (1'b0),
.PCSRSVDIN (1'b0),
.PCSRSVDIN2 (1'b0),
.PMARSVDIN (1'b0),
.PMARSVDIN2 (1'b0),
.TSTIN (1'b1),
.TSTOUT (),
.CLKRSVD (4'b0000),
.GTGREFCLK (1'b0),
.GTNORTHREFCLK0 (1'b0),
.GTNORTHREFCLK1 (1'b0),
.GTREFCLK0 (gtrefclk),
.GTREFCLK1 (1'b0),
.GTSOUTHREFCLK0 (1'b0),
.GTSOUTHREFCLK1 (1'b0),
.DRPADDR (9'b0),
.DRPCLK (drpclk),
.DRPDI (16'b0),
.DRPDO (),
.DRPEN (1'b0),
.DRPRDY (),
.DRPWE (1'b0),
.GTREFCLKMONITOR (),
.QPLLCLK (gtrefclk),
.QPLLREFCLK (gtrefclk),
.RXSYSCLKSEL (2'b00),
.TXSYSCLKSEL (2'b00),
.DMONITOROUT (),
.TX8B10BEN (1'b1),
.LOOPBACK (3'd0),
.PHYSTATUS (),
.RXRATE (3'd0),
.RXVALID (),
.RXPD (2'b00),
.TXPD (2'b00),
.SETERRSTATUS (1'b0),
.EYESCANRESET (1'b0),//rxreset), // p78
.RXUSERRDY (rxuserrdy),
.EYESCANDATAERROR (),
.EYESCANMODE (1'b0),
.EYESCANTRIGGER (1'b0),
.RXCDRFREQRESET (1'b0),
.RXCDRHOLD (1'b0),
.RXCDRLOCK (),
.RXCDROVRDEN (1'b0),
.RXCDRRESET (1'b0),
.RXCDRRESETRSV (1'b0),
.RXCLKCORCNT (),
.RX8B10BEN (1'b1),
.RXUSRCLK (rxusrclk),
.RXUSRCLK2 (rxusrclk2),
.RXDATA (rxdata),
.RXPRBSERR (),
.RXPRBSSEL (3'd0),
.RXPRBSCNTRESET (1'b0),
.RXDFEXYDEN (1'b1),
.RXDFEXYDHOLD (1'b0),
.RXDFEXYDOVRDEN (1'b0),
.RXDISPERR (),
.RXNOTINTABLE (),
.GTXRXP (rxp),
.GTXRXN (rxn),
.RXBUFRESET (1'b0),
.RXBUFSTATUS (),
.RXDDIEN (1'b0),
.RXDLYBYPASS (1'b1),
.RXDLYEN (1'b0),
.RXDLYOVRDEN (1'b0),
.RXDLYSRESET (1'b0),
.RXDLYSRESETDONE (),
.RXPHALIGN (1'b0),
.RXPHALIGNDONE (),
.RXPHALIGNEN (1'b0),
.RXPHDLYPD (1'b0),
.RXPHDLYRESET (1'b0),
.RXPHMONITOR (),
.RXPHOVRDEN (1'b0),
.RXPHSLIPMONITOR (),
.RXSTATUS (),
.RXBYTEISALIGNED (rxbyteisaligned),
.RXBYTEREALIGN (),
.RXCOMMADET (),
.RXCOMMADETEN (1'b1),
.RXMCOMMAALIGNEN (1'b1),
.RXPCOMMAALIGNEN (1'b1),
.RXCHANBONDSEQ (),
.RXCHBONDEN (1'b0),
.RXCHBONDLEVEL (3'd0),
.RXCHBONDMASTER (1'b0),
.RXCHBONDO (),
.RXCHBONDSLAVE (1'b0),
.RXCHANISALIGNED (),
.RXCHANREALIGN (),
.RXLPMHFHOLD (1'b0),
.RXLPMHFOVRDEN (1'b0),
.RXLPMLFHOLD (1'b0),
.RXDFEAGCHOLD (1'b0),
.RXDFEAGCOVRDEN (1'b0),
.RXDFECM1EN (1'b0),
.RXDFELFHOLD (1'b0),
.RXDFELFOVRDEN (1'b1),
.RXDFELPMRESET (rxreset),
.RXDFETAP2HOLD (1'b0),
.RXDFETAP2OVRDEN (1'b0),
.RXDFETAP3HOLD (1'b0),
.RXDFETAP3OVRDEN (1'b0),
.RXDFETAP4HOLD (1'b0),
.RXDFETAP4OVRDEN (1'b0),
.RXDFETAP5HOLD (1'b0),
.RXDFETAP5OVRDEN (1'b0),
.RXDFEUTHOLD (1'b0),
.RXDFEUTOVRDEN (1'b0),
.RXDFEVPHOLD (1'b0),
.RXDFEVPOVRDEN (1'b0),
// .RXDFEVSEN (1'b0),
.RXLPMLFKLOVRDEN (1'b0),
.RXMONITOROUT (),
.RXMONITORSEL (2'b01),
.RXOSHOLD (1'b0),
.RXOSOVRDEN (1'b0),
.RXRATEDONE (),
.RXOUTCLK (),
.RXOUTCLKFABRIC (),
.RXOUTCLKPCS (),
.RXOUTCLKSEL (3'b010),
.RXDATAVALID (),
.RXHEADER (),
.RXHEADERVALID (),
.RXSTARTOFSEQ (),
.RXGEARBOXSLIP (1'b0),
.GTRXRESET (rxreset),
.RXOOBRESET (1'b0),
.RXPCSRESET (1'b0),
.RXPMARESET (1'b0),//rxreset), // p78
.RXLPMEN (1'b0),
.RXCOMSASDET (),
.RXCOMWAKEDET (rxcomwakedet),
.RXCOMINITDET (rxcominitdet),
.RXELECIDLE (rxelecidle),
.RXELECIDLEMODE (2'b00),
.RXPOLARITY (1'b0),
.RXSLIDE (1'b0),
.RXCHARISCOMMA (),
.RXCHARISK (rxcharisk),
.RXCHBONDI (5'b00000),
.RXRESETDONE (rxresetdone),
.RXQPIEN (1'b0),
.RXQPISENN (),
.RXQPISENP (),
.TXPHDLYTSTCLK (1'b0),
.TXPOSTCURSOR (5'b00000),
.TXPOSTCURSORINV (1'b0),
.TXPRECURSOR (5'd0),
.TXPRECURSORINV (1'b0),
.TXQPIBIASEN (1'b0),
.TXQPISTRONGPDOWN (1'b0),
.TXQPIWEAKPUP (1'b0),
.CFGRESET (1'b0),
.GTTXRESET (txreset),
.PCSRSVDOUT (),
.TXUSERRDY (txuserrdy),
.GTRESETSEL (1'b0),
.RESETOVRD (1'b0),
.TXCHARDISPMODE (8'd0),
.TXCHARDISPVAL (8'd0),
.TXUSRCLK (txusrclk),
.TXUSRCLK2 (txusrclk2),
.TXELECIDLE (txelecidle),
.TXMARGIN (3'd0),
.TXRATE (3'd0),
.TXSWING (1'b0),
.TXPRBSFORCEERR (1'b0),
.TXDLYBYPASS (1'b1),
.TXDLYEN (1'b0),
.TXDLYHOLD (1'b0),
.TXDLYOVRDEN (1'b0),
.TXDLYSRESET (1'b0),
.TXDLYSRESETDONE (),
.TXDLYUPDOWN (1'b0),
.TXPHALIGN (1'b0),
.TXPHALIGNDONE (),
.TXPHALIGNEN (1'b0),
.TXPHDLYPD (1'b0),
.TXPHDLYRESET (1'b0),
.TXPHINIT (1'b0),
.TXPHINITDONE (),
.TXPHOVRDEN (1'b0),
.TXBUFSTATUS (),
.TXBUFDIFFCTRL (3'b100),
.TXDEEMPH (1'b0),
.TXDIFFCTRL (4'b1000),
.TXDIFFPD (1'b0),
.TXINHIBIT (1'b0),
.TXMAINCURSOR (7'b0000000),
.TXPISOPD (1'b0),
.TXDATA ({32'h0, txdata}),
.GTXTXN (txn),
.GTXTXP (txp),
.TXOUTCLK (txoutclk),
.TXOUTCLKFABRIC (),
.TXOUTCLKPCS (),
.TXOUTCLKSEL (3'b010),
.TXRATEDONE (),
.TXCHARISK ({7'b0, txcharisk}),
.TXGEARBOXREADY (),
.TXHEADER (3'd0),
.TXSEQUENCE (7'd0),
.TXSTARTSEQ (1'b0),
.TXPCSRESET (1'b0),
.TXPMARESET (1'b0),
.TXRESETDONE (txresetdone),
.TXCOMFINISH (),
.TXCOMINIT (txcominit),
.TXCOMSAS (1'b0),
.TXCOMWAKE (txcomwake),
.TXPDELECIDLEMODE (1'b0),
.TXPOLARITY (1'b0),
.TXDETECTRX (1'b0),
.TX8B10BBYPASS (8'd0),
.TXPRBSSEL (3'd0),
.TXQPISENN (),
.TXQPISENP ()/*,
.TXSYNCMODE (1'b0),
.TXSYNCALLIN (1'b0),
.TXSYNCIN (1'b0)*/
);
/*
* Interfaces
*/
assign DCMLOCKED_OUT = usrpll_locked;
assign PLLLKDET_OUT_N = cplllock;
assign rxn = RXN0_IN;
assign rxp = RXP0_IN;
assign TXN0_OUT = txn;
assign TXP0_OUT = txp;
assign cplllockdetclk = CLKIN_150;
assign drpclk = CLKIN_150;
assign LINKUP = linkup;
assign LINKUP_led = linkup_led;
assign rx_dataout = rxdata_out;
assign rx_charisk_out = rxcharisk_out;
assign rxelecidle_out = rxelecidle;
assign GEN2_led = 1'b0;
assign sata_user_clk = usrclk2;
endmodule
/*******************************************************************************
* Module: sata_top
* Date: 2015-07-11
* Author: Alexey
* Description: sata for z7nq top-level module
*
* Copyright (c) 2015 Elphel, Inc.
* sata_top.v 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.
*
* sata_top.v 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/> .
*******************************************************************************/
`timescale 1ns/1ns
`include "axi_regs.v"
`include "dma_regs.v"
`include "sata_host.v"
`include "dma_adapter.v"
`include "dma_control.v"
`include "membridge.v"
/*
* Takes commands from axi iface as a slave, transfers data with another axi iface as a master
*/
module sata_top(
/*
* Commands interface
*/
input wire ACLK, // AXI PS Master GP1 Clock , input
input wire ARESETN, // AXI PS Master GP1 Reset, output
// AXI PS Master GP1: Read Address
input wire [31:0] ARADDR, // AXI PS Master GP1 ARADDR[31:0], output
input wire ARVALID, // AXI PS Master GP1 ARVALID, output
output wire ARREADY, // AXI PS Master GP1 ARREADY, input
input wire [11:0] ARID, // AXI PS Master GP1 ARID[11:0], output
input wire [1:0] ARLOCK, // AXI PS Master GP1 ARLOCK[1:0], output
input wire [3:0] ARCACHE, // AXI PS Master GP1 ARCACHE[3:0], output
input wire [2:0] ARPROT, // AXI PS Master GP1 ARPROT[2:0], output
input wire [3:0] ARLEN, // AXI PS Master GP1 ARLEN[3:0], output
input wire [1:0] ARSIZE, // AXI PS Master GP1 ARSIZE[1:0], output
input wire [1:0] ARBURST, // AXI PS Master GP1 ARBURST[1:0], output
input wire [3:0] ARQOS, // AXI PS Master GP1 ARQOS[3:0], output
// AXI PS Master GP1: Read Data
output wire [31:0] RDATA, // AXI PS Master GP1 RDATA[31:0], input
output wire RVALID, // AXI PS Master GP1 RVALID, input
input wire RREADY, // AXI PS Master GP1 RREADY, output
output wire [11:0] RID, // AXI PS Master GP1 RID[11:0], input
output wire RLAST, // AXI PS Master GP1 RLAST, input
output wire [1:0] RRESP, // AXI PS Master GP1 RRESP[1:0], input
// AXI PS Master GP1: Write Address
input wire [31:0] AWADDR, // AXI PS Master GP1 AWADDR[31:0], output
input wire AWVALID, // AXI PS Master GP1 AWVALID, output
output wire AWREADY, // AXI PS Master GP1 AWREADY, input
input wire [11:0] AWID, // AXI PS Master GP1 AWID[11:0], output
input wire [1:0] AWLOCK, // AXI PS Master GP1 AWLOCK[1:0], output
input wire [3:0] AWCACHE, // AXI PS Master GP1 AWCACHE[3:0], output
input wire [2:0] AWPROT, // AXI PS Master GP1 AWPROT[2:0], output
input wire [3:0] AWLEN, // AXI PS Master GP1 AWLEN[3:0], outpu:t
input wire [1:0] AWSIZE, // AXI PS Master GP1 AWSIZE[1:0], output
input wire [1:0] AWBURST, // AXI PS Master GP1 AWBURST[1:0], output
input wire [3:0] AWQOS, // AXI PS Master GP1 AWQOS[3:0], output
// AXI PS Master GP1: Write Data
input wire [31:0] WDATA, // AXI PS Master GP1 WDATA[31:0], output
input wire WVALID, // AXI PS Master GP1 WVALID, output
output wire WREADY, // AXI PS Master GP1 WREADY, input
input wire [11:0] WID, // AXI PS Master GP1 WID[11:0], output
input wire WLAST, // AXI PS Master GP1 WLAST, output
input wire [3:0] WSTRB, // AXI PS Master GP1 WSTRB[3:0], output
// AXI PS Master GP1: Write Responce
output wire BVALID, // AXI PS Master GP1 BVALID, input
input wire BREADY, // AXI PS Master GP1 BREADY, output
output wire [11:0] BID, // AXI PS Master GP1 BID[11:0], input
output wire [1:0] BRESP, // AXI PS Master GP1 BRESP[1:0], input
/*
* Data interface
*/
output wire [31:0] afi_awaddr,
output wire afi_awvalid,
input wire afi_awready,
output wire [5:0] afi_awid,
output wire [1:0] afi_awlock,
output wire [3:0] afi_awcache,
output wire [2:0] afi_awprot,
output wire [3:0] afi_awlen,
output wire [2:0] afi_awsize,
output wire [1:0] afi_awburst,
output wire [3:0] afi_awqos,
// write data
output wire [63:0] afi_wdata,
output wire afi_wvalid,
input wire afi_wready,
output wire [5:0] afi_wid,
output wire afi_wlast,
output wire [7:0] afi_wstrb,
// write response
input wire afi_bvalid,
output wire afi_bready,
input wire [5:0] afi_bid,
input wire [1:0] afi_bresp,
// PL extra (non-AXI) signals
input wire [7:0] afi_wcount,
input wire [5:0] afi_wacount,
output wire afi_wrissuecap1en,
// AXI_HP signals - read channel
// read address
output wire [31:0] afi_araddr,
output wire afi_arvalid,
input wire afi_arready,
output wire [5:0] afi_arid,
output wire [1:0] afi_arlock,
output wire [3:0] afi_arcache,
output wire [2:0] afi_arprot,
output wire [3:0] afi_arlen,
output wire [2:0] afi_arsize,
output wire [1:0] afi_arburst,
output wire [3:0] afi_arqos,
// read data
input wire [63:0] afi_rdata,
input wire afi_rvalid,
output wire afi_rready,
input wire [5:0] afi_rid,
input wire afi_rlast,
input wire [1:0] afi_rresp,
// PL extra (non-AXI) signals
input wire [7:0] afi_rcount,
input wire [2:0] afi_racount,
output wire afi_rdissuecap1en,
/*
* PHY
*/
output wire TXN,
output wire TXP,
output wire RXN,
output wire RXP,
input wire REFCLK_PAD_P_IN,
input wire REFCLK_PAD_N_IN
);
// axi_regs <-> data regs
wire [31:0] bram_rdata;
wire [31:0] bram_waddr;
wire [31:0] bram_wdata;
wire [31:0] bram_raddr;
wire [3:0] bram_wstb;
wire bram_wen;
wire bram_ren;
wire bram_regen;
// sata logic reset
wire rst;
// sata clk
wire sclk;
// dma_regs <-> dma_control
wire [31:7] mem_address;
wire [31:0] lba;
wire [31:0] sector_cnt;
wire dma_type;
wire dma_start;
wire dma_done;
// axi-hp clock
wire hclk;
// dma_control <-> dma_adapter command iface
wire adp_busy;
wire [31:7] adp_addr;
wire adp_type;
wire adp_val;
// dma_control <-> sata_host command iface
wire host_ready_for_cmd;
wire host_new_cmd;
wire [1:0] host_cmd_type;
wire [31:0] host_sector_count;
wire [31:0] host_sector_addr;
// dma_control <-> dma_adapter data iface
wire [63:0] to_data;
wire to_val;
wire to_ack;
wire [63:0] from_data;
wire from_val;
wire from_ack;
// dma_control <-> sata_host data iface
wire [31:0] in_data;
wire in_val;
wire in_busy;
wire [31:0] out_data;
wire out_val;
wire out_busy;
// adapter <-> membridge iface
wire [7:0] cmd_ad;
wire cmd_stb;
wire [7:0] status_ad;
wire status_rq;
wire status_start;
wire frame_start_chn;
wire next_page_chn;
wire cmd_wrmem;
wire page_ready_chn;
wire frame_done_chn;
wire [15:0] line_unfinished_chn1;
wire suspend_chn1;
wire xfer_reset_page_rd;
wire buf_wpage_nxt;
wire buf_wr;
wire [63:0] buf_wdata;
wire xfer_reset_page_wr;
wire buf_rpage_nxt;
wire buf_rd;
wire [63:0] buf_rdata;
// additional adapter <-> membridge wire
wire rdata_done; // = membridge.is_last_in_page & membridge.afi_rready;
// sata_host timer
wire host_sata_timer;
// sata_host diag
wire host_linkup;
wire host_plllkdet;
wire host_dcmlocked;
// temporary 150Mhz clk
wire gtrefclk;
assign rst = ARESETN;
axi_regs axi_regs(
// axi iface
.ACLK (ACLK),
.ARESETN (ARESETN),
.ARADDR (ARADDR),
.ARVALID (ARVALID),
.ARREADY (ARREADY),
.ARID (ARID),
.ARLOCK (ARLOCK),
.ARCACHE (ARCACHE),
.ARPROT (ARPROT),
.ARLEN (ARLEN),
.ARSIZE (ARSIZE),
.ARBURST (ARBURST),
.ARQOS (ARQOS),
.RDATA (RDATA),
.RVALID (RVALID),
.RREADY (RREADY),
.RID (RID),
.RLAST (RLAST),
.RRESP (RRESP),
.AWADDR (AWADDR),
.AWVALID (AWVALID),
.AWREADY (AWREADY),
.AWID (AWID),
.AWLOCK (AWLOCK),
.AWCACHE (AWCACHE),
.AWPROT (AWPROT),
.AWLEN (AWLEN),
.AWSIZE (AWSIZE),
.AWBURST (AWBURST),
.AWQOS (AWQOS),
.WDATA (WDATA),
.WVALID (WVALID),
.WREADY (WREADY),
.WID (WID),
.WLAST (WLAST),
.WSTRB (WSTRB),
.BVALID (BVALID),
.BREADY (BREADY),
.BID (BID),
.BRESP (BRESP),
// registers iface
.bram_rdata (bram_rdata),
.bram_waddr (bram_waddr),
.bram_wdata (bram_wdata),
.bram_raddr (bram_raddr),
.bram_wstb (bram_wstb),
.bram_wen (bram_wen),
.bram_ren (bram_ren),
.bram_regen (bram_regen)
);
/*
* Programmable sata controller registers
*/
dma_regs dma_regs(
.rst (rst),
.ACLK (ACLK),
.sclk (sclk),
// control iface
.mem_address (mem_address),
.lba (lba),
.sector_cnt (sector_cnt),
.dma_type (dma_type),
.dma_start (dma_start),
.dma_done (dma_done),
// axi buffer iface
.bram_rdata (bram_rdata),
.bram_raddr (bram_raddr),
.bram_waddr (bram_waddr),
.bram_wdata (bram_wdata),
.bram_wstb (bram_wstb),
.bram_wen (bram_wen),
.bram_ren (bram_ren),
.bram_regen (bram_regen)
);
dma_control dma_control(
.sclk (sclk),
.hclk (hclk),
.rst (rst),
// registers iface
.mem_address (mem_address),
.lba (lba),
.sector_cnt (sector_cnt),
.dma_type (dma_type),
.dma_start (dma_start),
.dma_done (dma_done),
// adapter command iface
.adp_busy (adp_busy),
.adp_addr (adp_addr),
.adp_type (adp_type),
.adp_val (adp_val),
// sata host command iface
.host_ready_for_cmd (host_ready_for_cmd),
.host_new_cmd (host_new_cmd),
.host_cmd_type (host_cmd_type),
.host_sector_count (host_sector_count),
.host_sector_addr (host_sector_addr),
// adapter data iface
// to main memory
.to_data (to_data),
.to_val (to_val),
.to_ack (to_ack),
// from main memory
.from_data (from_data),
.from_val (from_val),
.from_ack (from_ack),
// sata host iface
// data from sata host
.in_data (in_data),
.in_val (in_val),
.in_busy (in_busy),
// data to sata host
.out_data (out_data),
.out_val (out_val),
.out_busy (out_busy)
);
//assign rdata_done = membridge.is_last_in_page & membridge.afi_rready;
dma_adapter dma_adapter(
.clk (hclk),
.rst (rst),
// command iface
.cmd_type (adp_type),
.cmd_val (adp_val),
.cmd_addr (adp_addr),
.cmd_busy (adp_busy),
// data iface
.wr_data_in (to_data),
.wr_val_in (to_val),
.wr_ack_out (to_ack),
.rd_data_out (from_data),
.rd_val_out (from_val),
.rd_ack_in (from_ack),
// membridge iface
.cmd_ad (cmd_ad),
.cmd_stb (cmd_stb),
.status_ad (status_ad),
.status_rq (status_rq),
.status_start (status_start),
.frame_start_chn (frame_start_chn),
.next_page_chn (next_page_chn),
.cmd_wrmem (cmd_wrmem),
.page_ready_chn (page_ready_chn),
.frame_done_chn (frame_done_chn),
.line_unfinished_chn1 (line_unfinished_chn1),
.suspend_chn1 (suspend_chn1),
.xfer_reset_page_rd (xfer_reset_page_rd),
.buf_wpage_nxt (buf_wpage_nxt),
.buf_wr (buf_wr),
.buf_wdata (buf_wdata),
.xfer_reset_page_wr (xfer_reset_page_wr),
.buf_rpage_nxt (buf_rpage_nxt),
.buf_rd (buf_rd),
.buf_rdata (buf_rdata),
.rdata_done (rdata_done)
);
membridge /*#(
.MEMBRIDGE_ADDR (),
.MEMBRIDGE_MASK (),
.MEMBRIDGE_CTRL (),
.MEMBRIDGE_STATUS_CNTRL (),
.MEMBRIDGE_LO_ADDR64 (),
.MEMBRIDGE_SIZE64 (),
.MEMBRIDGE_START64 (),
.MEMBRIDGE_LEN64 (),
.MEMBRIDGE_WIDTH64 (),
.MEMBRIDGE_MODE (),
.MEMBRIDGE_STATUS_REG (),
.FRAME_HEIGHT_BITS (),
.FRAME_WIDTH_BITS ()
)*/ membridge(
.rst (rst), // input
.mclk (hclk), // input
.hclk (hclk), // input
.cmd_ad (cmd_ad),
.cmd_stb (cmd_stb),
.status_ad (status_ad),
.status_rq (status_rq),
.status_start (status_start),
.frame_start_chn (frame_start_chn),
.next_page_chn (next_page_chn),
.cmd_wrmem (cmd_wrmem),
.page_ready_chn (page_ready_chn),
.frame_done_chn (frame_done_chn),
.line_unfinished_chn1 (line_unfinished_chn1),
.suspend_chn1 (suspend_chn1),
.xfer_reset_page_rd (xfer_reset_page_rd),
.buf_wpage_nxt (buf_wpage_nxt),
.buf_wr (buf_wr),
.buf_wdata (buf_wdata),
.xfer_reset_page_wr (xfer_reset_page_wr),
.buf_rpage_nxt (buf_rpage_nxt),
.buf_rd (buf_rd),
.buf_rdata (buf_rdata),
.afi_awaddr (afi_awaddr), // output[31:0]
.afi_awvalid (afi_awvalid), // output
.afi_awready (afi_awready), // input
.afi_awid (afi_awid), // output[5:0]
.afi_awlock (afi_awlock), // output[1:0]
.afi_awcache (afi_awcache), // output[3:0]
.afi_awprot (afi_awprot), // output[2:0]
.afi_awlen (afi_awlen), // output[3:0]
.afi_awsize (afi_awsize), // output[2:0]
.afi_awburst (afi_awburst), // output[1:0]
.afi_awqos (afi_awqos), // output[3:0]
.afi_wdata (afi_wdata), // output[63:0]
.afi_wvalid (afi_wvalid), // output
.afi_wready (afi_wready), // input
.afi_wid (afi_wid), // output[5:0]
.afi_wlast (afi_wlast), // output
.afi_wstrb (afi_wstrb), // output[7:0]
.afi_bvalid (afi_bvalid), // input
.afi_bready (afi_bready), // output
.afi_bid (afi_bid), // input[5:0]
.afi_bresp (afi_bresp), // input[1:0]
.afi_wcount (afi_wcount), // input[7:0]
.afi_wacount (afi_wacount), // input[5:0]
.afi_wrissuecap1en (afi_wrissuecap1en), // output
.afi_araddr (afi_araddr), // output[31:0]
.afi_arvalid (afi_arvalid), // output
.afi_arready (afi_arready), // input
.afi_arid (afi_arid), // output[5:0]
.afi_arlock (afi_arlock), // output[1:0]
.afi_arcache (afi_arcache), // output[3:0]
.afi_arprot (afi_arprot), // output[2:0]
.afi_arlen (afi_arlen), // output[3:0]
.afi_arsize (afi_arsize), // output[2:0]
.afi_arburst (afi_arburst), // output[1:0]
.afi_arqos (afi_arqos), // output[3:0]
.afi_rdata (afi_rdata), // input[63:0]
.afi_rvalid (afi_rvalid), // input
.afi_rready (afi_rready), // output
.afi_rid (afi_rid), // input[5:0]
.afi_rlast (afi_rlast), // input
.afi_rresp (afi_rresp), // input[2:0]
.afi_rcount (afi_rcount), // input[7:0]
.afi_racount (afi_racount), // input[2:0]
.afi_rdissuecap1en (afi_rdissuecap1en), // output
.rdata_done (rdata_done)
);
sata_host sata_host(
.ready_for_cmd (host_ready_for_cmd),
.new_cmd (host_new_cmd),
.cmd_type (host_cmd_type),
.sector_count (host_sector_count),
.sector_addr (host_sector_addr),
.sata_din (out_data),
.sata_din_we (out_val),
.sata_core_full (out_busy),
.sata_dout (in_data),
.sata_dout_re (in_val),
.sata_core_empty (in_busy),
.data_clk_in (sclk),
.data_clk_out (sclk),
.sata_timer (host_sata_timer),
.clkin_150 (gtrefclk),
.reset (rst),
.linkup (host_linkup),
.txp_out (TXP),
.txn_out (TXN),
.rxp_in (RXP),
.rxn_in (RXN),
.plllkdet (host_plllkdet),
.dcmlocked (host_dcmlocked)
);
/*
* Padding for an external input clock @ 150 MHz
* TODO!!! Shall be done on phy-level
*/
localparam [1:0] CLKSWING_CFG = 2'b11;
IBUFDS_GTE2 #(
.CLKRCV_TRST ("TRUE"),
.CLKCM_CFG ("TRUE"),
.CLKSWING_CFG (CLKSWING_CFG)
)
ext_clock_buf(
.I (REFCLK_PAD_P_IN),
.IB (REFCLK_PAD_N_IN),
.CEB (1'b0),
.O (gtrefclk),
.ODIV2 ()
);
endmodule
......@@ -7,9 +7,19 @@ then
fi
if [ "$UNISIMS_PATH" == '' ]
then
export UNISIMS_PATH="../../../../eddr3-src/eddr3/unisims"
export UNISIMS_PATH="../x393/unisims"
fi
iverilog $SATA_PATH/tb/tb_top.v $SATA_PATH/x393/glbl.v -f opts -stb -sglbl $1 2>&1| tee $LOGFILE_PATH
if [ "$HOST_PATH" == '' ]
then
export HOST_PATH="../host"
fi
if [ "$GTX_PATH" == '' ]
then
export GTX_PATH=$SATA_PATH
fi
iverilog -Wall $SATA_PATH/tb/tb_top.v $SATA_PATH/x393/glbl.v -I$SATA_PATH/tb -I$SATA_PATH -I$SATA_PATH/x393/axi -I$SATA_PATH/x393 -y$SATA_PATH/x393/util_modules -y$SATA_PATH/x393/wrap -y$UNISIMS_PATH -y$SATA_PATH/x393/memctrl -y$SATA_PATH/x393/axi -y$SATA_PATH/x393/simulation_modules $SATA_PATH/x393/simulation_modules/simul_axi_fifo_out.v -y$SATA_PATH/x393/
#iverilog $SATA_PATH/tb/tb_top.v $SATA_PATH/x393/glbl.v -f opts -stb -sglbl $1 2>&1| tee $LOGFILE_PATH
#-y$SATA_PATH/x393/util_modules -I$SATA_PATH/x393/ -I$SATA_PATH/x393/axi/ $SATA_PATH/tb/tb_axiregs.v -I$SATA_PATH/ -I$SATA_PATH/tb/
......@@ -330,8 +330,17 @@ simul_axi_read #(
.burst(), // burst in progress - just debug
.err_out()); // data last does not match predicted or FIFO over/under run - just debug
reg EXT_REF_CLK_P = 1'b1;
reg EXT_REF_CLK_N = 1'b0;
// device-under-test instance
top dut(
.RXN (1'b0),
.RXP (1'b0),
.TXN (),
.TXP (),
.REFCLK_PAD_P_IN (EXT_REF_CLK_P),
.REFCLK_PAD_N_IN (EXT_REF_CLK_N)
);
// SAXI HP interface
......
......@@ -22,6 +22,15 @@
* this file is included into tb_top.v due to the compatibility with x393 design testbench
*/
// external clock to gtx
always #3.333
begin
EXT_REF_CLK_P = ~EXT_REF_CLK_P;
EXT_REF_CLK_N = ~EXT_REF_CLK_N;
end
// write registers
initial
begin
CLK =1'b0;
......@@ -52,14 +61,14 @@ begin
// test SAXI3 iface
afi_setup(3);
axi_write_single(32'h10, 32'h0add9e55 >> 3); // addr
axi_write_single(32'h14, 32'h00000010); // size
axi_write_single(32'h18, 32'h00000010); // burst_len
axi_write_single(32'h20, 32'hdeadbee0); // data
axi_write_single(32'h24, 32'hdeadbee1); // data
axi_write_single(32'h28, 32'hdeadbee2); // data
axi_write_single(32'h10, 32'h0add9e55); // addr
axi_write_single(32'h14, 32'h12345678); // lba
axi_write_single(32'h18, 32'h00000020); // sector count
axi_write_single(32'h20, 32'h00100000); // dma type
axi_write_single(32'h24, 32'h00010000); // start
/* axi_write_single(32'h28, 32'hdeadbee2); // data
axi_write_single(32'h2c, 32'hdeadbee3); // data
axi_write_single(32'h1c, 32'hffffffff); // start
axi_write_single(32'h1c, 32'hffffffff); // start */
end
initial
......
......@@ -24,11 +24,19 @@
* what is called now 'axi_regs' and connect it
*/
`include "system_defines.vh"
`include "axi_regs.v"
`include "sata_top.v"
module top #(
`include "includes/x393_parameters.vh"
)
(
// sata serial data iface
input wire RXN,
input wire RXP,
output wire TXN,
output wire TXP,
// sata clocking iface
input wire REFCLK_PAD_P_IN,
input wire REFCLK_PAD_N_IN
);
parameter REGISTERS_CNT = 20;
wire [32*REGISTERS_CNT - 1:0] outmem;
......@@ -167,82 +175,118 @@ axi_hp_clk #(
.locked_axihp () // output // not controlled?
);
axi_regs #(
.REGISTERS_CNT (REGISTERS_CNT)
)
axi_regs(
.ACLK (axi_aclk),
.ARESETN (axi_rst),
.ARADDR (ARADDR),
.ARVALID (ARVALID),
.ARREADY (ARREADY),
.ARID (ARID),
.ARLOCK (ARLOCK),
.ARCACHE (ARCACHE),
.ARPROT (ARPROT),
.ARLEN (ARLEN),
.ARSIZE (ARSIZE),
.ARBURST (ARBURST),
.ARQOS (ARQOS),
.RDATA (RDATA),
.RVALID (RVALID),
.RREADY (RREADY),
.RID (RID),
.RLAST (RLAST),
.RRESP (RRESP),
.AWADDR (AWADDR),
.AWVALID (AWVALID),
.AWREADY (AWREADY),
.AWID (AWID),
.AWLOCK (AWLOCK),
.AWCACHE (AWCACHE),
.AWPROT (AWPROT),
.AWLEN (AWLEN),
.AWSIZE (AWSIZE),
.AWBURST (AWBURST),
.AWQOS (AWQOS),
.WDATA (WDATA),
.WVALID (WVALID),
.WREADY (WREADY),
.WID (WID),
.WLAST (WLAST),
.WSTRB (WSTRB),
.BVALID (BVALID),
.BREADY (BREADY),
.BID (BID),
.BRESP (BRESP),
.outmem (outmem),
.clrstart (clrstart)
);
sata_top sata_top(
.ACLK (axi_aclk),
.ARESETN (axi_rst),
// AXI PS Master GP1: Read Address
.ARADDR (ARADDR),
.ARVALID (ARVALID),
.ARREADY (ARREADY),
.ARID (ARID),
.ARLOCK (ARLOCK),
.ARCACHE (ARCACHE),
.ARPROT (ARPROT),
.ARLEN (ARLEN),
.ARSIZE (ARSIZE),
.ARBURST (ARBURST),
.ARQOS (ARQOS),
// AXI PS Master GP1: Read Data
.RDATA (RDATA),
.RVALID (RVALID),
.RREADY (RREADY),
.RID (RID),
.RLAST (RLAST),
.RRESP (RRESP),
// AXI PS Master GP1: Write Address
.AWADDR (AWADDR),
.AWVALID (AWVALID),
.AWREADY (AWREADY),
.AWID (AWID),
.AWLOCK (AWLOCK),
.AWCACHE (AWCACHE),
.AWPROT (AWPROT),
.AWLEN (AWLEN),
.AWSIZE (AWSIZE),
.AWBURST (AWBURST),
.AWQOS (AWQOS),
// AXI PS Master GP1: Write Data
.WDATA (WDATA),
.WVALID (WVALID),
.WREADY (WREADY),
.WID (WID),
.WLAST (WLAST),
.WSTRB (WSTRB),
// AXI PS Master GP1: Write Responce
.BVALID (BVALID),
.BREADY (BREADY),
.BID (BID),
.BRESP (BRESP),
dma_adapter #(
.REGISTERS_CNT (REGISTERS_CNT)
)
dma_adapter(
.clk (axi_aclk),
.rst (axi_rst),
.mem (outmem),
.clrstart (clrstart),
.cmd_ad (cmd_ad),
.cmd_stb (cmd_stb),
.status_ad (status_ad),
.status_rq (status_rq),
.status_start (status_start),
.frame_start_chn (frame_start_chn),
.next_page_chn (next_page_chn),
.cmd_wrmem (cmd_wrmem),
.page_ready_chn (page_ready_chn),
.frame_done_chn (frame_done_chn),
.line_unfinished_chn1 (line_unfinished_chn1),
.suspend_chn1 (suspend_chn1),
.xfer_reset_page_rd (xfer_reset_page_rd),
.buf_wpage_nxt (buf_wpage_nxt),
.buf_wr (buf_wr),
.buf_wdata (buf_wdata),
.xfer_reset_page_wr (xfer_reset_page_wr),
.buf_rpage_nxt (buf_rpage_nxt),
.buf_rd (buf_rd),
.buf_rdata (buf_rdata)
/*
* Data interface
*/
.afi_awaddr (afi0_awaddr),
.afi_awvalid (afi0_awvalid),
.afi_awready (afi0_awready),
.afi_awid (afi0_awid),
.afi_awlock (afi0_awlock),
.afi_awcache (afi0_awcache),
.afi_awprot (afi0_awprot),
.afi_awlen (afi0_awlen),
.afi_awsize (afi0_awsize),
.afi_awburst (afi0_awburst),
.afi_awqos (afi0_awqos),
// write data
.afi_wdata (afi0_wdata),
.afi_wvalid (afi0_wvalid),
.afi_wready (afi0_wready),
.afi_wid (afi0_wid),
.afi_wlast (afi0_wlast),
.afi_wstrb (afi0_wstrb),
// write response
.afi_bvalid (afi0_bvalid),
.afi_bready (afi0_bready),
.afi_bid (afi0_bid),
.afi_bresp (afi0_bresp),
// PL extra (non-AXI) signal
.afi_wcount (afi0_wcount),
.afi_wacount (afi0_wacount),
.afi_wrissuecap1en (afi0_wrissuecap1en),
// AXI_HP signals - read channel
// read address
.afi_araddr (afi0_araddr),
.afi_arvalid (afi0_arvalid),
.afi_arready (afi0_arready),
.afi_arid (afi0_arid),
.afi_arlock (afi0_arlock),
.afi_arcache (afi0_arcache),
.afi_arprot (afi0_arprot),
.afi_arlen (afi0_arlen),
.afi_arsize (afi0_arsize),
.afi_arburst (afi0_arburst),
.afi_arqos (afi0_arqos),
// read data
.afi_rdata (afi0_rdata),
.afi_rvalid (afi0_rvalid),
.afi_rready (afi0_rready),
.afi_rid (afi0_rid),
.afi_rlast (afi0_rlast),
.afi_rresp (afi0_rresp),
// PL extra (non-AXI) signal
.afi_rcount (afi0_rcount),
.afi_racount (afi0_racount),
.afi_rdissuecap1en (afi0_rdissuecap1en),
/*
* PHY
*/
.TXN (TXN),
.TXP (TXP),
.RXN (RXN),
.RXP (RXP),
.REFCLK_PAD_P_IN (REFCLK_PAD_P_IN),
.REFCLK_PAD_N_IN (REFCLK_PAD_N_IN)
);
PS7 ps7_i (
......@@ -987,89 +1031,4 @@ PS7 ps7_i (
.PSPORB(), // PS PSPORB, inout
.PSSRSTB() // PS PSSRSTB, inout
);
membridge /*#(
.MEMBRIDGE_ADDR (),
.MEMBRIDGE_MASK (),
.MEMBRIDGE_CTRL (),
.MEMBRIDGE_STATUS_CNTRL (),
.MEMBRIDGE_LO_ADDR64 (),
.MEMBRIDGE_SIZE64 (),
.MEMBRIDGE_START64 (),
.MEMBRIDGE_LEN64 (),
.MEMBRIDGE_WIDTH64 (),
.MEMBRIDGE_MODE (),
.MEMBRIDGE_STATUS_REG (),
.FRAME_HEIGHT_BITS (),
.FRAME_WIDTH_BITS ()
)*/ membridge_i (
.rst (axi_rst), // input
.mclk (axi_aclk), // input
.hclk (hclk), // input
.cmd_ad (cmd_ad),
.cmd_stb (cmd_stb),
.status_ad (status_ad),
.status_rq (status_rq),
.status_start (status_start),
.frame_start_chn (frame_start_chn),
.next_page_chn (next_page_chn),
.cmd_wrmem (cmd_wrmem),
.page_ready_chn (page_ready_chn),
.frame_done_chn (frame_done_chn),
.line_unfinished_chn1 (line_unfinished_chn1),
.suspend_chn1 (suspend_chn1),
.xfer_reset_page_rd (xfer_reset_page_rd),
.buf_wpage_nxt (buf_wpage_nxt),
.buf_wr (buf_wr),
.buf_wdata (buf_wdata),
.xfer_reset_page_wr (xfer_reset_page_wr),
.buf_rpage_nxt (buf_rpage_nxt),
.buf_rd (buf_rd),
.buf_rdata (buf_rdata),
.afi_awaddr (afi0_awaddr), // output[31:0]
.afi_awvalid (afi0_awvalid), // output
.afi_awready (afi0_awready), // input
.afi_awid (afi0_awid), // output[5:0]
.afi_awlock (afi0_awlock), // output[1:0]
.afi_awcache (afi0_awcache), // output[3:0]
.afi_awprot (afi0_awprot), // output[2:0]
.afi_awlen (afi0_awlen), // output[3:0]
.afi_awsize (afi0_awsize), // output[2:0]
.afi_awburst (afi0_awburst), // output[1:0]
.afi_awqos (afi0_awqos), // output[3:0]
.afi_wdata (afi0_wdata), // output[63:0]
.afi_wvalid (afi0_wvalid), // output
.afi_wready (afi0_wready), // input
.afi_wid (afi0_wid), // output[5:0]
.afi_wlast (afi0_wlast), // output
.afi_wstrb (afi0_wstrb), // output[7:0]
.afi_bvalid (afi0_bvalid), // input
.afi_bready (afi0_bready), // output
.afi_bid (afi0_bid), // input[5:0]
.afi_bresp (afi0_bresp), // input[1:0]
.afi_wcount (afi0_wcount), // input[7:0]
.afi_wacount (afi0_wacount), // input[5:0]
.afi_wrissuecap1en (afi0_wrissuecap1en), // output
.afi_araddr (afi0_araddr), // output[31:0]
.afi_arvalid (afi0_arvalid), // output
.afi_arready (afi0_arready), // input
.afi_arid (afi0_arid), // output[5:0]
.afi_arlock (afi0_arlock), // output[1:0]
.afi_arcache (afi0_arcache), // output[3:0]
.afi_arprot (afi0_arprot), // output[2:0]
.afi_arlen (afi0_arlen), // output[3:0]
.afi_arsize (afi0_arsize), // output[2:0]
.afi_arburst (afi0_arburst), // output[1:0]
.afi_arqos (afi0_arqos), // output[3:0]
.afi_rdata (afi0_rdata), // input[63:0]
.afi_rvalid (afi0_rvalid), // input
.afi_rready (afi0_rready), // output
.afi_rid (afi0_rid), // input[5:0]
.afi_rlast (afi0_rlast), // input
.afi_rresp (afi0_rresp), // input[2:0]
.afi_rcount (afi0_rcount), // input[7:0]
.afi_racount (afi0_racount), // input[2:0]
.afi_rdissuecap1en (afi0_rdissuecap1en) // output
);
endmodule
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