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

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

parent 3153826e
Loading
Loading
Loading
Loading
+15 −74
Original line number Diff line number Diff line
@@ -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)
+43 −41
Original line number Diff line number Diff line
@@ -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,7 +149,7 @@ always @ (posedge clk)
        rd_en           <= 1'b0;
    end
    else
        case (rst)
        case (rdwr_state)
            READ_IDLE:
            begin
                rdwr_state      <= rd_start ? READ_WAIT_ADDR : READ_IDLE;
@@ -159,7 +160,7 @@ always @ (posedge clk)
            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;
                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;
@@ -181,6 +182,7 @@ always @ (posedge clk)
                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:
+206 −43
Original line number Diff line number Diff line
@@ -19,8 +19,10 @@
 * 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
@@ -35,6 +37,19 @@
   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,
@@ -43,7 +58,7 @@
   // from main memory
   input   wire    [63:0]  from_data,
   input   wire            from_val,
    input   wire            from_ack
   output  wire            from_ack,

   // sata host iface
   // data from sata host
@@ -55,7 +70,156 @@
   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

dma_regs.v

0 → 100644
+152 −0
Original line number Diff line number Diff line
/*******************************************************************************
 * 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
+42 −4
Original line number Diff line number Diff line
@@ -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
Loading