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
This diff is collapsed.
This diff is collapsed.
......@@ -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
......
This diff is collapsed.
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