Loading dma_regs.v +148 −15 Original line number Diff line number Diff line Loading @@ -40,7 +40,73 @@ module dma_regs #( input wire [3:0] bram_wstb, input wire bram_wen, input wire bram_ren, input wire bram_regen input wire bram_regen, // tmp to cmd control output wire cmd_val_out, output wire [31:0] cmd_out, // tmp to shadow registers output wire [31:0] sh_data, // write data output wire sh_data_val, // write strobe output wire sh_data_strobe, // read strobe output wire [15:0] sh_feature, output wire sh_feature_val, output wire [23:0] sh_lba_lo, output wire sh_lba_lo_val, output wire [23:0] sh_lba_hi, output wire sh_lba_hi_val, output wire [15:0] sh_count, output wire sh_count_val, output wire [7:0] sh_command, output wire sh_command_val, output wire [7:0] sh_dev, output wire sh_dev_val, output wire [7:0] sh_control, output wire sh_control_val, output wire [31:0] sh_dma_id_lo output wire sh_dma_id_lo_val, output wire [31:0] sh_dma_id_hi, output wire sh_dma_id_hi_val, output wire [31:0] sh_buf_off, output wire sh_buf_off_val, output wire [31:0] sh_dma_cnt, output wire sh_dma_cnt_val, output wire [31:0] sh_tran_cnt, output wire sh_tran_cnt_val, output wire sh_autoact, output wire sh_autoact_val, output wire sh_inter, output wire sh_inter_val, output wire [3:0] sh_port, output wire sh_port_val, output wire sh_notif, output wire sh_notif_val, output wire sh_dir, output wire sh_dir_val, // inputs from sh registers input wire sh_data_val_in, input wire [31:0] sh_data_in, input wire [7:0] sh_control_in, input wire [15:0] sh_feature_in, input wire [47:0] sh_lba_in, input wire [15:0] sh_count_in, input wire [7:0] sh_command_in, input wire [7:0] sh_err_in, input wire [7:0] sh_status_in, input wire [7:0] sh_estatus_in, // E_Status input wire [7:0] sh_dev_in, input wire [3:0] sh_port_in, input wire sh_inter_in, input wire sh_dir_in, input wire [63:0] sh_dma_id_in, input wire [31:0] sh_dma_off_in, input wire [31:0] sh_dma_cnt_in, input wire [15:0] sh_tran_cnt_in, // Transfer Count input wire sh_notif_in, input wire sh_autoact_in // inputs from cmd control input wire [31:0] cmd_in ); //reg [32*REGISTERS_CNT - 1:0] mem; /* Loading Loading @@ -86,7 +152,7 @@ pulse_cross_clock dma_start_pulse( .busy () ); assign dma_start_aclk = bram_wen & (bram_waddr[3:0] == 4'h4) & |wdata; assign dma_start_aclk = bram_wen & (bram_waddr[7:0] == 8'hf4) & |wdata; assign wdata = bram_wdata[31:0] & {{8{bram_wstb[3]}}, {8{bram_wstb[2]}}, {8{bram_wstb[1]}}, {8{bram_wstb[0]}}}; always @ (posedge ACLK) Loading @@ -99,26 +165,93 @@ assign dma_type = |reg0c; always @ (posedge ACLK) begin reg00 <= rst ? 32'h0 : bram_wen & (bram_waddr[3:0] == 4'h0) ? wdata : reg00; reg04 <= rst ? 32'h0 : bram_wen & (bram_waddr[3:0] == 4'h1) ? wdata : reg04; reg08 <= rst ? 32'h0 : bram_wen & (bram_waddr[3:0] == 4'h2) ? wdata : reg08; reg0c <= rst ? 32'h0 : bram_wen & (bram_waddr[3:0] == 4'h3) ? wdata : reg0c; reg00 <= rst ? 32'h0 : bram_wen & (bram_waddr[7:0] == 8'hf0) ? wdata : reg00; reg04 <= rst ? 32'h0 : bram_wen & (bram_waddr[7:0] == 8'hf1) ? wdata : reg04; reg08 <= rst ? 32'h0 : bram_wen & (bram_waddr[7:0] == 8'hf2) ? wdata : reg08; reg0c <= rst ? 32'h0 : bram_wen & (bram_waddr[7:0] == 8'hf3) ? wdata : reg0c; reg10 <= rst ? 32'h0 : dma_start_aclk ? 32'h0 : dma_done_aclk ? 32'hffffffff : reg10; // status reg reg14 <= rst ? 32'h0 : dma_done_aclk ? reg00 : reg14; end // writes to shadow registers: assign sh_data_val = bram_wen & (bram_waddr[7:0] == 8'h0); assign sh_feature_val = bram_wen & (bram_waddr[7:0] == 8'h1); assign sh_lba_lo_val = bram_wen & (bram_waddr[7:0] == 8'h2); assign sh_lba_hi_val = bram_wen & (bram_waddr[7:0] == 8'h3); assign sh_count_val = bram_wen & (bram_waddr[7:0] == 8'h4); assign sh_command_val = bram_wen & (bram_waddr[7:0] == 8'h5); assign sh_dev_val = bram_wen & (bram_waddr[7:0] == 8'h6); assign sh_control_val = bram_wen & (bram_waddr[7:0] == 8'h7); assign sh_dma_id_lo_val = bram_wen & (bram_waddr[7:0] == 8'h8); assign sh_dma_id_hi_val = bram_wen & (bram_waddr[7:0] == 8'h9); assign sh_buf_off_val = bram_wen & (bram_waddr[7:0] == 8'ha); assign sh_tran_cnt_val = bram_wen & (bram_waddr[7:0] == 8'hb); assign sh_autoact_val = bram_wen & (bram_waddr[7:0] == 8'hc); assign sh_inter_val = bram_wen & (bram_waddr[7:0] == 8'hd); assign sh_dir_val = bram_wen & (bram_waddr[7:0] == 8'he); assign cmd_val_out = bram_wen & (bram_waddr[7:0] == 8'hf); assign sh_port = bram_wen & (bram_waddr[7:0] == 8'h13); assign sh_dma_cnt_val = bram_wen & (bram_waddr[7:0] == 8'h14); assign sh_notif_val = bram_wen & (bram_waddr[7:0] == 8'h15); assign sh_data = wdata; assign sh_feature = wdata; assign sh_lba_lo = wdata; assign sh_lba_hi = wdata; assign sh_count = wdata; assign sh_command = wdata; assign sh_dev = wdata; assign sh_control = wdata; assign sh_dma_id_lo = wdata; assign sh_dma_id_hi = wdata; assign sh_buf_off = wdata; assign sh_tran_cnt = wdata; assign sh_autoact = wdata; assign sh_inter = wdata; assign sh_dir = wdata; assign sh_port = wdata; assign sh_notif = wdata; assign sh_dma_cnt = wdata; assign cmd_out = wdata; assign sh_data_strobe = bram_regen & bram_raddr_r == 8'h00; // read from registers. Interface's protocol assumes returning data with a delay reg [3:0] bram_raddr_r; reg [7:0] bram_raddr_r; reg [31:0] bram_rdata_r; always @ (posedge ACLK) begin bram_raddr_r <= bram_ren ? bram_raddr[3:0] : bram_raddr_r; bram_raddr_r <= bram_ren ? bram_raddr[7:0] : bram_raddr_r; bram_rdata_r <= ~bram_regen ? bram_rdata_r : bram_raddr_r == 4'h0 ? reg00 : bram_raddr_r == 4'h1 ? reg04 : bram_raddr_r == 4'h2 ? reg08 : bram_raddr_r == 4'h3 ? reg0c : bram_raddr_r == 4'h4 ? reg10 : bram_raddr_r == 4'h5 ? reg14 : bram_raddr_r == 8'hf0 ? reg00 : bram_raddr_r == 8'hf1 ? reg04 : bram_raddr_r == 8'hf2 ? reg08 : bram_raddr_r == 8'hf3 ? reg0c : bram_raddr_r == 8'hf4 ? reg10 : bram_raddr_r == 8'hf5 ? reg14 : bram_raddr_r == 8'h00 ? sh_data_in : bram_raddr_r == 8'h01 ? sh_feature_in : bram_raddr_r == 8'h02 ? sh_lba_in[23:0] : bram_raddr_r == 8'h03 ? sh_lba_in[47:24] : bram_raddr_r == 8'h04 ? sh_count_in : bram_raddr_r == 8'h05 ? sh_command_in : bram_raddr_r == 8'h06 ? sh_dev_in : bram_raddr_r == 8'h07 ? sh_control_in : bram_raddr_r == 8'h08 ? sh_dma_id_in[31:0] : bram_raddr_r == 8'h09 ? sh_dma_id_in[63:32] : bram_raddr_r == 8'h0a ? sh_dma_off_in : bram_raddr_r == 8'h0b ? sh_tran_cnt_in : // Transfer Count bram_raddr_r == 8'h0c ? sh_autoact_in : bram_raddr_r == 8'h0d ? sh_inter_in : bram_raddr_r == 8'h0e ? sh_dir_in : bram_raddr_r == 8'h0f ? cmd_in : bram_raddr_r == 8'h10 ? sh_err_in : bram_raddr_r == 8'h11 ? sh_status_in : bram_raddr_r == 8'h12 ? sh_estatus_in : // E_Status bram_raddr_r == 8'h13 ? sh_port_in : bram_raddr_r == 8'h14 ? sh_dma_cnt_in : bram_raddr_r == 8'h15 ? sh_notif_in : 32'hd34db33f; end assign bram_rdata = bram_rdata_r; Loading host/command.v 0 → 100644 +275 −0 Original line number Diff line number Diff line /******************************************************************************* * Module: command * Date: 2015-07-11 * Author: Alexey * Description: sata command layer temporary implementation * * Copyright (c) 2015 Elphel, Inc. * command.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. * * command.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/> . *******************************************************************************/ /* * For testing purposes almost neat, manually-controlled */ module command( input rst, input clk, // tl cmd iface output wire [2:0] cmd_type, output wire cmd_val, output wire [3:0] cmd_port, input wire cmd_busy, input wire cmd_done_good, input wire cmd_done_bad, // temporary TODO input wire [31:0] al_cmd_in, // == {cmd_type, cmd_port, cmd_val, cmd_done_bad, cmd_done_good, cmd_busy} input wire al_cmd_val_in, output wire [31:0] al_cmd_out, // same // data from tl input wire [31:0] tl_data_in, input wire tl_data_val_in, input wire tl_data_last_in, output wire tl_data_busy_out, // to tl output wire [31:0] tl_data_out, output wire tl_data_last_out, output wire tl_data_val_out, input wire tl_data_strobe_in, // tmp inputs directly from registers for each and every shadow register and control bit // from al input wire [31:0] al_sh_data_in, // write data input wire al_sh_data_val_in, // write strobe input wire al_sh_data_strobe_in, // read strobe input wire [15:0] al_sh_feature_in, input wire al_sh_feature_val_in, input wire [23:0] al_sh_lba_lo_in, input wire al_sh_lba_lo_val_in, input wire [23:0] al_sh_lba_hi_in, input wire al_sh_lba_hi_val_in, input wire [15:0] al_sh_count_in, input wire al_sh_count_val_in, input wire [7:0] al_sh_command_in, input wire al_sh_command_val_in, input wire [7:0] al_sh_dev_in, input wire al_sh_dev_val_in, input wire [7:0] al_sh_control_in, input wire al_sh_control_val_in, input wire [31:0] al_sh_dma_id_lo_in, input wire al_sh_dma_id_lo_val_in, input wire [31:0] al_sh_dma_id_hi_in, input wire al_sh_dma_id_hi_val_in, input wire [31:0] al_sh_buf_off_in, input wire al_sh_buf_off_val_in, input wire [31:0] al_sh_tran_cnt_in, input wire al_sh_tran_cnt_val_in, input wire al_sh_autoact_in, input wire al_sh_autoact_val_in, input wire al_sh_inter_in, input wire al_sh_inter_val_in, input wire al_sh_dir_in, input wire al_sh_dir_val_in, input wire [31:0] al_sh_dma_cnt_in, input wire al_sh_dma_cnt_val_in, input wire al_sh_notif_in, input wire al_sh_notif_val_in, input wire [3:0] al_sh_port_in, input wire al_sh_port_val_in, // from tl input wire [47:0] tl_sh_lba_in, input wire [15:0] tl_sh_count_in, input wire [7:0] tl_sh_command_in, input wire [7:0] tl_sh_err_in, input wire [7:0] tl_sh_status_in, input wire [7:0] tl_sh_estatus_in, // E_Status input wire [7:0] tl_sh_dev_in, input wire [3:0] tl_sh_port_in, input wire tl_sh_inter_in, input wire tl_sh_dir_in, input wire [63:0] tl_sh_dma_id_in, input wire [31:0] tl_sh_dma_off_in, input wire [31:0] tl_sh_dma_cnt_in, input wire [15:0] tl_sh_tran_cnt_in, // Transfer Count input wire tl_sh_notif_in, input wire tl_sh_autoact_in, input wire tl_sh_lba_val_in, input wire tl_sh_count_val_in, input wire tl_sh_command_val_in, input wire tl_sh_err_val_in, input wire tl_sh_status_val_in, input wire tl_sh_estatus_val_in, // E_Status input wire tl_sh_dev_val_in, input wire tl_sh_port_val_in, input wire tl_sh_inter_val_in, input wire tl_sh_dir_val_in, input wire tl_sh_dma_id_val_in, input wire tl_sh_dma_off_val_in, input wire tl_sh_dma_cnt_val_in, input wire tl_sh_tran_cnt_val_in, // Transfer Count input wire tl_sh_notif_val_in, input wire tl_sh_autoact_val_in, // all regs to output output wire sh_data_val_out, output wire [31:0] sh_data_out, output wire [7:0] sh_control_out, output wire [15:0] sh_feature_out, output wire [47:0] sh_lba_out, output wire [15:0] sh_count_out, output wire [7:0] sh_command_out, output wire [7:0] sh_err_out, output wire [7:0] sh_status_out, output wire [7:0] sh_estatus_out, // E_Status output wire [7:0] sh_dev_out, output wire [3:0] sh_port_out, output wire sh_inter_out, output wire sh_dir_out, output wire [63:0] sh_dma_id_out, output wire [31:0] sh_dma_off_out, output wire [31:0] sh_dma_cnt_out, output wire [15:0] sh_tran_cnt_out, // Transfer Count output wire sh_notif_out, output wire sh_autoact_out ); // shadow registers wire [31:0] sh_data; reg [7:0] sh_control; reg [15:0] sh_feature; reg [47:0] sh_lba; reg [15:0] sh_count; reg [7:0] sh_command; reg [7:0] sh_err; reg [7:0] sh_status; reg [7:0] sh_estatus; // E_Status reg [7:0] sh_dev; reg [3:0] sh_port; reg sh_inter; reg sh_dir; reg [63:0] sh_dma_id; reg [31:0] sh_dma_off; reg [31:0] sh_dma_cnt; reg [15:0] sh_tran_cnt; // Transfer Count reg sh_notif; reg sh_autoact; always @ (posedge clk) begin // sh_data <= rst ? 32'h0 : al_sh_data_val_in ? al_sh_data_in : /*tl_sh_data_val_in ? tl_sh_data_in :*/ sh_data; sh_control <= rst ? 8'h0 : al_sh_control_val_in ? al_sh_control_in : /*tl_sh_control_val_in ? tl_sh_control_in :*/ sh_control; sh_feature <= rst ? 16'h0 : al_sh_feature_val_in ? al_sh_feature_in : /*tl_sh_feature_val_in ? tl_sh_feature_in :*/ sh_feature; sh_lba[23:0] <= rst ? 24'h0 : al_sh_lba_lo_val_in ? al_sh_lba_lo_in : tl_sh_lba_val_in ? tl_sh_lba_in[23:0] : sh_lba[23:0]; sh_lba[47:24] <= rst ? 24'h0 : al_sh_lba_hi_val_in ? al_sh_lba_hi_in : tl_sh_lba_val_in ? tl_sh_lba_in[47:24] : sh_lba[47:24]; sh_count <= rst ? 16'h0 : al_sh_count_val_in ? al_sh_count_in : tl_sh_count_val_in ? tl_sh_count_in : sh_count; sh_command <= rst ? 8'h0 : al_sh_command_val_in ? al_sh_command_in : tl_sh_command_val_in ? tl_sh_command_in : sh_command; sh_err <= rst ? 8'h0 :/* al_sh_err_val_in ? al_sh_err_in :*/ tl_sh_err_val_in ? tl_sh_err_in : sh_err; sh_status <= rst ? 8'h0 :/* al_sh_status_val_in ? al_sh_status_in :*/ tl_sh_status_val_in ? tl_sh_status_in : sh_status; sh_estatus <= rst ? 8'h0 :/* al_sh_estatus_val_in ? al_sh_estatus_in :*/ tl_sh_estatus_val_in ? tl_sh_estatus_in : sh_estatus; sh_dev <= rst ? 8'h0 : al_sh_dev_val_in ? al_sh_dev_in : tl_sh_dev_val_in ? tl_sh_dev_in : sh_dev; sh_port <= rst ? 4'h0 : al_sh_port_val_in ? al_sh_port_in : tl_sh_port_val_in ? tl_sh_port_in : sh_port; sh_inter <= rst ? 1'h0 : al_sh_inter_val_in ? al_sh_inter_in : tl_sh_inter_val_in ? tl_sh_inter_in : sh_inter; sh_dir <= rst ? 1'h0 : al_sh_dir_val_in ? al_sh_dir_in : tl_sh_dir_val_in ? tl_sh_dir_in : sh_dir; sh_dma_id[31:0] <= rst ? 32'h0 : al_sh_dma_id_lo_val_in ? al_sh_dma_id_lo_in : tl_sh_dma_id_val_in ? tl_sh_dma_id_in[31:0] : sh_dma_id[31:0]; sh_dma_id[63:32] <= rst ? 32'h0 : al_sh_dma_id_lo_val_in ? al_sh_dma_id_hi_in : tl_sh_dma_id_val_in ? tl_sh_dma_id_in[63:32] : sh_dma_id[63:32]; sh_dma_off <= rst ? 32'h0 : al_sh_buf_off_val_in ? al_sh_buf_off_in : tl_sh_dma_off_val_in ? tl_sh_dma_off_in : sh_dma_off; sh_dma_cnt <= rst ? 32'h0 : al_sh_dma_cnt_val_in ? al_sh_dma_cnt_in : tl_sh_dma_cnt_val_in ? tl_sh_dma_cnt_in : sh_dma_cnt; sh_tran_cnt <= rst ? 32'h0 : al_sh_tran_cnt_val_in ? al_sh_tran_cnt_in : tl_sh_tran_cnt_val_in ? tl_sh_tran_cnt_in : sh_tran_cnt; sh_notif <= rst ? 1'h0 : al_sh_notif_val_in ? al_sh_notif_in : tl_sh_notif_val_in ? tl_sh_notif_in : sh_notif; sh_autoact <= rst ? 1'h0 : al_sh_autoact_val_in ? al_sh_autoact_in : tl_sh_autoact_val_in ? tl_sh_autoact_in : sh_autoact; end // outputs assignment assign sh_data_out = sh_data; assign sh_control_out = sh_control; assign sh_feature_out = sh_feature; assign sh_lba_out = sh_lba; assign sh_count_out = sh_count; assign sh_command_out = sh_command; assign sh_err_out = sh_err; assign sh_status_out = sh_status; assign sh_estatus_out = sh_estatus; assign sh_dev_out = sh_dev; assign sh_port_out = sh_port; assign sh_inter_out = sh_inter; assign sh_dir_out = sh_dir; assign sh_dma_id_out = sh_dma_id; assign sh_dma_off_out = sh_dma_off; assign sh_dma_cnt_out = sh_dma_cnt; assign sh_tran_cnt_out = sh_tran_cnt; assign sh_notif_out = sh_notif; assign sh_autoact_out = sh_autoact; // temporaty command register TODO reg [31:0] cmd; assign al_cmd_out = cmd; always @ (posedge clk) begin cmd[31:4] <= rst ? 28'h0 : al_cmd_val_in ? al_cmd_in : cmd; cmd[3] <= rst ? 1'b0 : al_cmd_val_in ? al_cmd_in[3] : cmd_val ? 1'b0 : cmd[3]; cmd[2] <= rst ? 1'b0 : al_cmd_val_in ? 1'b0 : cmd_done_bad ? 1'b1 : cmd[2]; cmd[1] <= rst ? 1'b0 : al_cmd_val_in ? 1'b0 : cmd_done_good ? 1'b1 : cmd[2]; cmd[0] <= rst ? 1'b0 : al_cmd_val_in ? 1'b0 : cmd_busy; end assign cmd_val = ~cmd_busy & cmd[3]; assign cmd_type = cmd[10:8]; assign cmd_port = cmd[7:4]; // data read buffer, 2048 dwords reg [9:0] raddr; reg [9:0] waddr; assign tl_data_busy_out = 1'b0; assign tl_data_out = 32'h0; assign tl_data_last_out = 1'b0; assign tl_data_val_out = 1'b0; always @ (posedge clk) waddr <= rst ? 1'b0 : ~tl_data_val_in ? waddr : (raddr == waddr + 1'b1) ? waddr : waddr + 1'b1; always @ (posedge clk) raddr <= rst ? 1'b0 : al_sh_data_strobe_in ? raddr + 1'b1 : waddr; ram_1kx32_1kx32 rbuf( .rclk (clk), // clock for read port .raddr (raddr), // read address .ren (al_sh_data_strobe_in), // read port enable .regen (1'b0), // output register enable .data_out (sh_data), // data out .wclk (clk), // clock for read port .waddr (waddr), // write address .we (tl_data_val_in), // write port enable .web (4'hf), .data_in (tl_data_in) // data out ); endmodule Loading
dma_regs.v +148 −15 Original line number Diff line number Diff line Loading @@ -40,7 +40,73 @@ module dma_regs #( input wire [3:0] bram_wstb, input wire bram_wen, input wire bram_ren, input wire bram_regen input wire bram_regen, // tmp to cmd control output wire cmd_val_out, output wire [31:0] cmd_out, // tmp to shadow registers output wire [31:0] sh_data, // write data output wire sh_data_val, // write strobe output wire sh_data_strobe, // read strobe output wire [15:0] sh_feature, output wire sh_feature_val, output wire [23:0] sh_lba_lo, output wire sh_lba_lo_val, output wire [23:0] sh_lba_hi, output wire sh_lba_hi_val, output wire [15:0] sh_count, output wire sh_count_val, output wire [7:0] sh_command, output wire sh_command_val, output wire [7:0] sh_dev, output wire sh_dev_val, output wire [7:0] sh_control, output wire sh_control_val, output wire [31:0] sh_dma_id_lo output wire sh_dma_id_lo_val, output wire [31:0] sh_dma_id_hi, output wire sh_dma_id_hi_val, output wire [31:0] sh_buf_off, output wire sh_buf_off_val, output wire [31:0] sh_dma_cnt, output wire sh_dma_cnt_val, output wire [31:0] sh_tran_cnt, output wire sh_tran_cnt_val, output wire sh_autoact, output wire sh_autoact_val, output wire sh_inter, output wire sh_inter_val, output wire [3:0] sh_port, output wire sh_port_val, output wire sh_notif, output wire sh_notif_val, output wire sh_dir, output wire sh_dir_val, // inputs from sh registers input wire sh_data_val_in, input wire [31:0] sh_data_in, input wire [7:0] sh_control_in, input wire [15:0] sh_feature_in, input wire [47:0] sh_lba_in, input wire [15:0] sh_count_in, input wire [7:0] sh_command_in, input wire [7:0] sh_err_in, input wire [7:0] sh_status_in, input wire [7:0] sh_estatus_in, // E_Status input wire [7:0] sh_dev_in, input wire [3:0] sh_port_in, input wire sh_inter_in, input wire sh_dir_in, input wire [63:0] sh_dma_id_in, input wire [31:0] sh_dma_off_in, input wire [31:0] sh_dma_cnt_in, input wire [15:0] sh_tran_cnt_in, // Transfer Count input wire sh_notif_in, input wire sh_autoact_in // inputs from cmd control input wire [31:0] cmd_in ); //reg [32*REGISTERS_CNT - 1:0] mem; /* Loading Loading @@ -86,7 +152,7 @@ pulse_cross_clock dma_start_pulse( .busy () ); assign dma_start_aclk = bram_wen & (bram_waddr[3:0] == 4'h4) & |wdata; assign dma_start_aclk = bram_wen & (bram_waddr[7:0] == 8'hf4) & |wdata; assign wdata = bram_wdata[31:0] & {{8{bram_wstb[3]}}, {8{bram_wstb[2]}}, {8{bram_wstb[1]}}, {8{bram_wstb[0]}}}; always @ (posedge ACLK) Loading @@ -99,26 +165,93 @@ assign dma_type = |reg0c; always @ (posedge ACLK) begin reg00 <= rst ? 32'h0 : bram_wen & (bram_waddr[3:0] == 4'h0) ? wdata : reg00; reg04 <= rst ? 32'h0 : bram_wen & (bram_waddr[3:0] == 4'h1) ? wdata : reg04; reg08 <= rst ? 32'h0 : bram_wen & (bram_waddr[3:0] == 4'h2) ? wdata : reg08; reg0c <= rst ? 32'h0 : bram_wen & (bram_waddr[3:0] == 4'h3) ? wdata : reg0c; reg00 <= rst ? 32'h0 : bram_wen & (bram_waddr[7:0] == 8'hf0) ? wdata : reg00; reg04 <= rst ? 32'h0 : bram_wen & (bram_waddr[7:0] == 8'hf1) ? wdata : reg04; reg08 <= rst ? 32'h0 : bram_wen & (bram_waddr[7:0] == 8'hf2) ? wdata : reg08; reg0c <= rst ? 32'h0 : bram_wen & (bram_waddr[7:0] == 8'hf3) ? wdata : reg0c; reg10 <= rst ? 32'h0 : dma_start_aclk ? 32'h0 : dma_done_aclk ? 32'hffffffff : reg10; // status reg reg14 <= rst ? 32'h0 : dma_done_aclk ? reg00 : reg14; end // writes to shadow registers: assign sh_data_val = bram_wen & (bram_waddr[7:0] == 8'h0); assign sh_feature_val = bram_wen & (bram_waddr[7:0] == 8'h1); assign sh_lba_lo_val = bram_wen & (bram_waddr[7:0] == 8'h2); assign sh_lba_hi_val = bram_wen & (bram_waddr[7:0] == 8'h3); assign sh_count_val = bram_wen & (bram_waddr[7:0] == 8'h4); assign sh_command_val = bram_wen & (bram_waddr[7:0] == 8'h5); assign sh_dev_val = bram_wen & (bram_waddr[7:0] == 8'h6); assign sh_control_val = bram_wen & (bram_waddr[7:0] == 8'h7); assign sh_dma_id_lo_val = bram_wen & (bram_waddr[7:0] == 8'h8); assign sh_dma_id_hi_val = bram_wen & (bram_waddr[7:0] == 8'h9); assign sh_buf_off_val = bram_wen & (bram_waddr[7:0] == 8'ha); assign sh_tran_cnt_val = bram_wen & (bram_waddr[7:0] == 8'hb); assign sh_autoact_val = bram_wen & (bram_waddr[7:0] == 8'hc); assign sh_inter_val = bram_wen & (bram_waddr[7:0] == 8'hd); assign sh_dir_val = bram_wen & (bram_waddr[7:0] == 8'he); assign cmd_val_out = bram_wen & (bram_waddr[7:0] == 8'hf); assign sh_port = bram_wen & (bram_waddr[7:0] == 8'h13); assign sh_dma_cnt_val = bram_wen & (bram_waddr[7:0] == 8'h14); assign sh_notif_val = bram_wen & (bram_waddr[7:0] == 8'h15); assign sh_data = wdata; assign sh_feature = wdata; assign sh_lba_lo = wdata; assign sh_lba_hi = wdata; assign sh_count = wdata; assign sh_command = wdata; assign sh_dev = wdata; assign sh_control = wdata; assign sh_dma_id_lo = wdata; assign sh_dma_id_hi = wdata; assign sh_buf_off = wdata; assign sh_tran_cnt = wdata; assign sh_autoact = wdata; assign sh_inter = wdata; assign sh_dir = wdata; assign sh_port = wdata; assign sh_notif = wdata; assign sh_dma_cnt = wdata; assign cmd_out = wdata; assign sh_data_strobe = bram_regen & bram_raddr_r == 8'h00; // read from registers. Interface's protocol assumes returning data with a delay reg [3:0] bram_raddr_r; reg [7:0] bram_raddr_r; reg [31:0] bram_rdata_r; always @ (posedge ACLK) begin bram_raddr_r <= bram_ren ? bram_raddr[3:0] : bram_raddr_r; bram_raddr_r <= bram_ren ? bram_raddr[7:0] : bram_raddr_r; bram_rdata_r <= ~bram_regen ? bram_rdata_r : bram_raddr_r == 4'h0 ? reg00 : bram_raddr_r == 4'h1 ? reg04 : bram_raddr_r == 4'h2 ? reg08 : bram_raddr_r == 4'h3 ? reg0c : bram_raddr_r == 4'h4 ? reg10 : bram_raddr_r == 4'h5 ? reg14 : bram_raddr_r == 8'hf0 ? reg00 : bram_raddr_r == 8'hf1 ? reg04 : bram_raddr_r == 8'hf2 ? reg08 : bram_raddr_r == 8'hf3 ? reg0c : bram_raddr_r == 8'hf4 ? reg10 : bram_raddr_r == 8'hf5 ? reg14 : bram_raddr_r == 8'h00 ? sh_data_in : bram_raddr_r == 8'h01 ? sh_feature_in : bram_raddr_r == 8'h02 ? sh_lba_in[23:0] : bram_raddr_r == 8'h03 ? sh_lba_in[47:24] : bram_raddr_r == 8'h04 ? sh_count_in : bram_raddr_r == 8'h05 ? sh_command_in : bram_raddr_r == 8'h06 ? sh_dev_in : bram_raddr_r == 8'h07 ? sh_control_in : bram_raddr_r == 8'h08 ? sh_dma_id_in[31:0] : bram_raddr_r == 8'h09 ? sh_dma_id_in[63:32] : bram_raddr_r == 8'h0a ? sh_dma_off_in : bram_raddr_r == 8'h0b ? sh_tran_cnt_in : // Transfer Count bram_raddr_r == 8'h0c ? sh_autoact_in : bram_raddr_r == 8'h0d ? sh_inter_in : bram_raddr_r == 8'h0e ? sh_dir_in : bram_raddr_r == 8'h0f ? cmd_in : bram_raddr_r == 8'h10 ? sh_err_in : bram_raddr_r == 8'h11 ? sh_status_in : bram_raddr_r == 8'h12 ? sh_estatus_in : // E_Status bram_raddr_r == 8'h13 ? sh_port_in : bram_raddr_r == 8'h14 ? sh_dma_cnt_in : bram_raddr_r == 8'h15 ? sh_notif_in : 32'hd34db33f; end assign bram_rdata = bram_rdata_r; Loading
host/command.v 0 → 100644 +275 −0 Original line number Diff line number Diff line /******************************************************************************* * Module: command * Date: 2015-07-11 * Author: Alexey * Description: sata command layer temporary implementation * * Copyright (c) 2015 Elphel, Inc. * command.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. * * command.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/> . *******************************************************************************/ /* * For testing purposes almost neat, manually-controlled */ module command( input rst, input clk, // tl cmd iface output wire [2:0] cmd_type, output wire cmd_val, output wire [3:0] cmd_port, input wire cmd_busy, input wire cmd_done_good, input wire cmd_done_bad, // temporary TODO input wire [31:0] al_cmd_in, // == {cmd_type, cmd_port, cmd_val, cmd_done_bad, cmd_done_good, cmd_busy} input wire al_cmd_val_in, output wire [31:0] al_cmd_out, // same // data from tl input wire [31:0] tl_data_in, input wire tl_data_val_in, input wire tl_data_last_in, output wire tl_data_busy_out, // to tl output wire [31:0] tl_data_out, output wire tl_data_last_out, output wire tl_data_val_out, input wire tl_data_strobe_in, // tmp inputs directly from registers for each and every shadow register and control bit // from al input wire [31:0] al_sh_data_in, // write data input wire al_sh_data_val_in, // write strobe input wire al_sh_data_strobe_in, // read strobe input wire [15:0] al_sh_feature_in, input wire al_sh_feature_val_in, input wire [23:0] al_sh_lba_lo_in, input wire al_sh_lba_lo_val_in, input wire [23:0] al_sh_lba_hi_in, input wire al_sh_lba_hi_val_in, input wire [15:0] al_sh_count_in, input wire al_sh_count_val_in, input wire [7:0] al_sh_command_in, input wire al_sh_command_val_in, input wire [7:0] al_sh_dev_in, input wire al_sh_dev_val_in, input wire [7:0] al_sh_control_in, input wire al_sh_control_val_in, input wire [31:0] al_sh_dma_id_lo_in, input wire al_sh_dma_id_lo_val_in, input wire [31:0] al_sh_dma_id_hi_in, input wire al_sh_dma_id_hi_val_in, input wire [31:0] al_sh_buf_off_in, input wire al_sh_buf_off_val_in, input wire [31:0] al_sh_tran_cnt_in, input wire al_sh_tran_cnt_val_in, input wire al_sh_autoact_in, input wire al_sh_autoact_val_in, input wire al_sh_inter_in, input wire al_sh_inter_val_in, input wire al_sh_dir_in, input wire al_sh_dir_val_in, input wire [31:0] al_sh_dma_cnt_in, input wire al_sh_dma_cnt_val_in, input wire al_sh_notif_in, input wire al_sh_notif_val_in, input wire [3:0] al_sh_port_in, input wire al_sh_port_val_in, // from tl input wire [47:0] tl_sh_lba_in, input wire [15:0] tl_sh_count_in, input wire [7:0] tl_sh_command_in, input wire [7:0] tl_sh_err_in, input wire [7:0] tl_sh_status_in, input wire [7:0] tl_sh_estatus_in, // E_Status input wire [7:0] tl_sh_dev_in, input wire [3:0] tl_sh_port_in, input wire tl_sh_inter_in, input wire tl_sh_dir_in, input wire [63:0] tl_sh_dma_id_in, input wire [31:0] tl_sh_dma_off_in, input wire [31:0] tl_sh_dma_cnt_in, input wire [15:0] tl_sh_tran_cnt_in, // Transfer Count input wire tl_sh_notif_in, input wire tl_sh_autoact_in, input wire tl_sh_lba_val_in, input wire tl_sh_count_val_in, input wire tl_sh_command_val_in, input wire tl_sh_err_val_in, input wire tl_sh_status_val_in, input wire tl_sh_estatus_val_in, // E_Status input wire tl_sh_dev_val_in, input wire tl_sh_port_val_in, input wire tl_sh_inter_val_in, input wire tl_sh_dir_val_in, input wire tl_sh_dma_id_val_in, input wire tl_sh_dma_off_val_in, input wire tl_sh_dma_cnt_val_in, input wire tl_sh_tran_cnt_val_in, // Transfer Count input wire tl_sh_notif_val_in, input wire tl_sh_autoact_val_in, // all regs to output output wire sh_data_val_out, output wire [31:0] sh_data_out, output wire [7:0] sh_control_out, output wire [15:0] sh_feature_out, output wire [47:0] sh_lba_out, output wire [15:0] sh_count_out, output wire [7:0] sh_command_out, output wire [7:0] sh_err_out, output wire [7:0] sh_status_out, output wire [7:0] sh_estatus_out, // E_Status output wire [7:0] sh_dev_out, output wire [3:0] sh_port_out, output wire sh_inter_out, output wire sh_dir_out, output wire [63:0] sh_dma_id_out, output wire [31:0] sh_dma_off_out, output wire [31:0] sh_dma_cnt_out, output wire [15:0] sh_tran_cnt_out, // Transfer Count output wire sh_notif_out, output wire sh_autoact_out ); // shadow registers wire [31:0] sh_data; reg [7:0] sh_control; reg [15:0] sh_feature; reg [47:0] sh_lba; reg [15:0] sh_count; reg [7:0] sh_command; reg [7:0] sh_err; reg [7:0] sh_status; reg [7:0] sh_estatus; // E_Status reg [7:0] sh_dev; reg [3:0] sh_port; reg sh_inter; reg sh_dir; reg [63:0] sh_dma_id; reg [31:0] sh_dma_off; reg [31:0] sh_dma_cnt; reg [15:0] sh_tran_cnt; // Transfer Count reg sh_notif; reg sh_autoact; always @ (posedge clk) begin // sh_data <= rst ? 32'h0 : al_sh_data_val_in ? al_sh_data_in : /*tl_sh_data_val_in ? tl_sh_data_in :*/ sh_data; sh_control <= rst ? 8'h0 : al_sh_control_val_in ? al_sh_control_in : /*tl_sh_control_val_in ? tl_sh_control_in :*/ sh_control; sh_feature <= rst ? 16'h0 : al_sh_feature_val_in ? al_sh_feature_in : /*tl_sh_feature_val_in ? tl_sh_feature_in :*/ sh_feature; sh_lba[23:0] <= rst ? 24'h0 : al_sh_lba_lo_val_in ? al_sh_lba_lo_in : tl_sh_lba_val_in ? tl_sh_lba_in[23:0] : sh_lba[23:0]; sh_lba[47:24] <= rst ? 24'h0 : al_sh_lba_hi_val_in ? al_sh_lba_hi_in : tl_sh_lba_val_in ? tl_sh_lba_in[47:24] : sh_lba[47:24]; sh_count <= rst ? 16'h0 : al_sh_count_val_in ? al_sh_count_in : tl_sh_count_val_in ? tl_sh_count_in : sh_count; sh_command <= rst ? 8'h0 : al_sh_command_val_in ? al_sh_command_in : tl_sh_command_val_in ? tl_sh_command_in : sh_command; sh_err <= rst ? 8'h0 :/* al_sh_err_val_in ? al_sh_err_in :*/ tl_sh_err_val_in ? tl_sh_err_in : sh_err; sh_status <= rst ? 8'h0 :/* al_sh_status_val_in ? al_sh_status_in :*/ tl_sh_status_val_in ? tl_sh_status_in : sh_status; sh_estatus <= rst ? 8'h0 :/* al_sh_estatus_val_in ? al_sh_estatus_in :*/ tl_sh_estatus_val_in ? tl_sh_estatus_in : sh_estatus; sh_dev <= rst ? 8'h0 : al_sh_dev_val_in ? al_sh_dev_in : tl_sh_dev_val_in ? tl_sh_dev_in : sh_dev; sh_port <= rst ? 4'h0 : al_sh_port_val_in ? al_sh_port_in : tl_sh_port_val_in ? tl_sh_port_in : sh_port; sh_inter <= rst ? 1'h0 : al_sh_inter_val_in ? al_sh_inter_in : tl_sh_inter_val_in ? tl_sh_inter_in : sh_inter; sh_dir <= rst ? 1'h0 : al_sh_dir_val_in ? al_sh_dir_in : tl_sh_dir_val_in ? tl_sh_dir_in : sh_dir; sh_dma_id[31:0] <= rst ? 32'h0 : al_sh_dma_id_lo_val_in ? al_sh_dma_id_lo_in : tl_sh_dma_id_val_in ? tl_sh_dma_id_in[31:0] : sh_dma_id[31:0]; sh_dma_id[63:32] <= rst ? 32'h0 : al_sh_dma_id_lo_val_in ? al_sh_dma_id_hi_in : tl_sh_dma_id_val_in ? tl_sh_dma_id_in[63:32] : sh_dma_id[63:32]; sh_dma_off <= rst ? 32'h0 : al_sh_buf_off_val_in ? al_sh_buf_off_in : tl_sh_dma_off_val_in ? tl_sh_dma_off_in : sh_dma_off; sh_dma_cnt <= rst ? 32'h0 : al_sh_dma_cnt_val_in ? al_sh_dma_cnt_in : tl_sh_dma_cnt_val_in ? tl_sh_dma_cnt_in : sh_dma_cnt; sh_tran_cnt <= rst ? 32'h0 : al_sh_tran_cnt_val_in ? al_sh_tran_cnt_in : tl_sh_tran_cnt_val_in ? tl_sh_tran_cnt_in : sh_tran_cnt; sh_notif <= rst ? 1'h0 : al_sh_notif_val_in ? al_sh_notif_in : tl_sh_notif_val_in ? tl_sh_notif_in : sh_notif; sh_autoact <= rst ? 1'h0 : al_sh_autoact_val_in ? al_sh_autoact_in : tl_sh_autoact_val_in ? tl_sh_autoact_in : sh_autoact; end // outputs assignment assign sh_data_out = sh_data; assign sh_control_out = sh_control; assign sh_feature_out = sh_feature; assign sh_lba_out = sh_lba; assign sh_count_out = sh_count; assign sh_command_out = sh_command; assign sh_err_out = sh_err; assign sh_status_out = sh_status; assign sh_estatus_out = sh_estatus; assign sh_dev_out = sh_dev; assign sh_port_out = sh_port; assign sh_inter_out = sh_inter; assign sh_dir_out = sh_dir; assign sh_dma_id_out = sh_dma_id; assign sh_dma_off_out = sh_dma_off; assign sh_dma_cnt_out = sh_dma_cnt; assign sh_tran_cnt_out = sh_tran_cnt; assign sh_notif_out = sh_notif; assign sh_autoact_out = sh_autoact; // temporaty command register TODO reg [31:0] cmd; assign al_cmd_out = cmd; always @ (posedge clk) begin cmd[31:4] <= rst ? 28'h0 : al_cmd_val_in ? al_cmd_in : cmd; cmd[3] <= rst ? 1'b0 : al_cmd_val_in ? al_cmd_in[3] : cmd_val ? 1'b0 : cmd[3]; cmd[2] <= rst ? 1'b0 : al_cmd_val_in ? 1'b0 : cmd_done_bad ? 1'b1 : cmd[2]; cmd[1] <= rst ? 1'b0 : al_cmd_val_in ? 1'b0 : cmd_done_good ? 1'b1 : cmd[2]; cmd[0] <= rst ? 1'b0 : al_cmd_val_in ? 1'b0 : cmd_busy; end assign cmd_val = ~cmd_busy & cmd[3]; assign cmd_type = cmd[10:8]; assign cmd_port = cmd[7:4]; // data read buffer, 2048 dwords reg [9:0] raddr; reg [9:0] waddr; assign tl_data_busy_out = 1'b0; assign tl_data_out = 32'h0; assign tl_data_last_out = 1'b0; assign tl_data_val_out = 1'b0; always @ (posedge clk) waddr <= rst ? 1'b0 : ~tl_data_val_in ? waddr : (raddr == waddr + 1'b1) ? waddr : waddr + 1'b1; always @ (posedge clk) raddr <= rst ? 1'b0 : al_sh_data_strobe_in ? raddr + 1'b1 : waddr; ram_1kx32_1kx32 rbuf( .rclk (clk), // clock for read port .raddr (raddr), // read address .ren (al_sh_data_strobe_in), // read port enable .regen (1'b0), // output register enable .data_out (sh_data), // data out .wclk (clk), // clock for read port .waddr (waddr), // write address .we (tl_data_val_in), // write port enable .web (4'hf), .data_in (tl_data_in) // data out ); endmodule