Add adv_dbg_if files
diff --git a/verilog/rtl/ips/adv_dbg_if b/verilog/rtl/ips/adv_dbg_if deleted file mode 160000 index 20655af..0000000 --- a/verilog/rtl/ips/adv_dbg_if +++ /dev/null
@@ -1 +0,0 @@ -Subproject commit 20655aff9c4bfdeabf928f75e035e5e36bfc54f9
diff --git a/verilog/rtl/ips/adv_dbg_if/rtl/adbg_axi_biu.v b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_axi_biu.v new file mode 100644 index 0000000..bd432c1 --- /dev/null +++ b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_axi_biu.v
@@ -0,0 +1,443 @@ +module adbg_axi_biu +#( + parameter AXI_ADDR_WIDTH = 32, + parameter AXI_DATA_WIDTH = 64, + parameter AXI_USER_WIDTH = 6, + parameter AXI_ID_WIDTH = 3 +) +( + tck_i, + trstn_i, + data_i, + data_o, + addr_i, + strobe_i, + rd_wrn_i, + rdy_o, + err_o, + word_size_i, + axi_aclk, + axi_aresetn, + axi_master_aw_valid, + axi_master_aw_addr, + axi_master_aw_prot, + axi_master_aw_region, + axi_master_aw_len, + axi_master_aw_size, + axi_master_aw_burst, + axi_master_aw_lock, + axi_master_aw_cache, + axi_master_aw_qos, + axi_master_aw_id, + axi_master_aw_user, + axi_master_aw_ready, + axi_master_ar_valid, + axi_master_ar_addr, + axi_master_ar_prot, + axi_master_ar_region, + axi_master_ar_len, + axi_master_ar_size, + axi_master_ar_burst, + axi_master_ar_lock, + axi_master_ar_cache, + axi_master_ar_qos, + axi_master_ar_id, + axi_master_ar_user, + axi_master_ar_ready, + axi_master_w_valid, + axi_master_w_data, + axi_master_w_strb, + axi_master_w_user, + axi_master_w_last, + axi_master_w_ready, + axi_master_r_valid, + axi_master_r_data, + axi_master_r_resp, + axi_master_r_last, + axi_master_r_id, + axi_master_r_user, + axi_master_r_ready, + axi_master_b_valid, + axi_master_b_resp, + axi_master_b_id, + axi_master_b_user, + axi_master_b_ready +); + //parameter AXI_ADDR_WIDTH = 32; + //parameter AXI_DATA_WIDTH = 64; + //parameter AXI_USER_WIDTH = 6; + //parameter AXI_ID_WIDTH = 3; + input wire tck_i; + input wire trstn_i; + input wire [63:0] data_i; + output reg [63:0] data_o; + input wire [31:0] addr_i; + input wire strobe_i; + input wire rd_wrn_i; + output reg rdy_o; + output wire err_o; + input wire [3:0] word_size_i; + input wire axi_aclk; + input wire axi_aresetn; + output reg axi_master_aw_valid; + output wire [AXI_ADDR_WIDTH - 1:0] axi_master_aw_addr; + output wire [2:0] axi_master_aw_prot; + output wire [3:0] axi_master_aw_region; + output wire [7:0] axi_master_aw_len; + output reg [2:0] axi_master_aw_size; + output wire [1:0] axi_master_aw_burst; + output wire axi_master_aw_lock; + output wire [3:0] axi_master_aw_cache; + output wire [3:0] axi_master_aw_qos; + output wire [AXI_ID_WIDTH - 1:0] axi_master_aw_id; + output wire [AXI_USER_WIDTH - 1:0] axi_master_aw_user; + input wire axi_master_aw_ready; + output reg axi_master_ar_valid; + output wire [AXI_ADDR_WIDTH - 1:0] axi_master_ar_addr; + output wire [2:0] axi_master_ar_prot; + output wire [3:0] axi_master_ar_region; + output wire [7:0] axi_master_ar_len; + output reg [2:0] axi_master_ar_size; + output wire [1:0] axi_master_ar_burst; + output wire axi_master_ar_lock; + output wire [3:0] axi_master_ar_cache; + output wire [3:0] axi_master_ar_qos; + output wire [AXI_ID_WIDTH - 1:0] axi_master_ar_id; + output wire [AXI_USER_WIDTH - 1:0] axi_master_ar_user; + input wire axi_master_ar_ready; + output reg axi_master_w_valid; + output wire [AXI_DATA_WIDTH - 1:0] axi_master_w_data; + output wire [(AXI_DATA_WIDTH / 8) - 1:0] axi_master_w_strb; + output wire [AXI_USER_WIDTH - 1:0] axi_master_w_user; + output wire axi_master_w_last; + input wire axi_master_w_ready; + input wire axi_master_r_valid; + input wire [AXI_DATA_WIDTH - 1:0] axi_master_r_data; + input wire [1:0] axi_master_r_resp; + input wire axi_master_r_last; + input wire [AXI_ID_WIDTH - 1:0] axi_master_r_id; + input wire [AXI_USER_WIDTH - 1:0] axi_master_r_user; + output reg axi_master_r_ready; + input wire axi_master_b_valid; + input wire [1:0] axi_master_b_resp; + input wire [AXI_ID_WIDTH - 1:0] axi_master_b_id; + input wire [AXI_USER_WIDTH - 1:0] axi_master_b_user; + output reg axi_master_b_ready; + reg [(AXI_DATA_WIDTH / 8) - 1:0] sel_reg; + reg [AXI_ADDR_WIDTH - 1:0] addr_reg; + reg [AXI_DATA_WIDTH - 1:0] data_in_reg; + reg [AXI_DATA_WIDTH - 1:0] data_out_reg; + reg wr_reg; + reg str_sync; + reg rdy_sync; + reg err_reg; + reg rdy_sync_tff1; + reg rdy_sync_tff2; + reg rdy_sync_tff2q; + reg str_sync_wbff1; + reg str_sync_wbff2; + reg str_sync_wbff2q; + reg data_o_en; + reg rdy_sync_en; + reg err_en; + reg [(AXI_DATA_WIDTH / 8) - 1:0] be_dec; + wire start_toggle; + reg [AXI_DATA_WIDTH - 1:0] swapped_data_i; + reg [AXI_DATA_WIDTH - 1:0] swapped_data_out; + reg [1:0] axi_fsm_state; + reg [1:0] next_fsm_state; + always @(*) + if (AXI_DATA_WIDTH == 64) + case (word_size_i) + 4'h1: + if (addr_i[2:0] == 3'b000) + be_dec = 8'b00000001; + else if (addr_i[2:0] == 3'b001) + be_dec = 8'b00000010; + else if (addr_i[2:0] == 3'b010) + be_dec = 8'b00000100; + else if (addr_i[2:0] == 3'b011) + be_dec = 8'b00001000; + else if (addr_i[2:0] == 3'b100) + be_dec = 8'b00010000; + else if (addr_i[2:0] == 3'b101) + be_dec = 8'b00100000; + else if (addr_i[2:0] == 3'b110) + be_dec = 8'b01000000; + else + be_dec = 8'b10000000; + 4'h2: + if (addr_i[2:1] == 2'b00) + be_dec = 8'b00000011; + else if (addr_i[2:1] == 2'b01) + be_dec = 8'b00001100; + else if (addr_i[2:1] == 2'b10) + be_dec = 8'b00110000; + else + be_dec = 8'b11000000; + 4'h4: + if (addr_i[2] == 1'b0) + be_dec = 8'b00001111; + else + be_dec = 8'b11110000; + 4'h8: be_dec = 8'b11111111; + default: be_dec = 8'b11111111; + endcase + else if (AXI_DATA_WIDTH == 32) + case (word_size_i) + 4'h1: + if (addr_i[1:0] == 2'b00) + be_dec = 4'b0001; + else if (addr_i[1:0] == 2'b01) + be_dec = 4'b0010; + else if (addr_i[1:0] == 2'b10) + be_dec = 4'b0100; + else + be_dec = 4'b1000; + 4'h2: + if (addr_i[1] == 1'b0) + be_dec = 4'b0011; + else + be_dec = 4'b1100; + 4'h4: be_dec = 4'b1111; + 4'h8: be_dec = 4'b1111; + default: be_dec = 4'b1111; + endcase + always @(*) + if (AXI_DATA_WIDTH == 64) + case (be_dec) + 8'b00001111: swapped_data_i = {32'h00000000, data_i[63:32]}; + 8'b11110000: swapped_data_i = {data_i[63:32], 32'h00000000}; + 8'b00000011: swapped_data_i = {48'h000000000000, data_i[63:48]}; + 8'b00001100: swapped_data_i = {32'h00000000, data_i[63:48], 16'h0000}; + 8'b00110000: swapped_data_i = {16'h0000, data_i[63:48], 32'h00000000}; + 8'b11000000: swapped_data_i = {data_i[63:48], 48'h000000000000}; + 8'b00000001: swapped_data_i = {56'h00000000000000, data_i[63:56]}; + 8'b00000010: swapped_data_i = {48'h000000000000, data_i[63:56], 8'h00}; + 8'b00000100: swapped_data_i = {40'h0000000000, data_i[63:56], 16'h0000}; + 8'b00001000: swapped_data_i = {32'h00000000, data_i[63:56], 24'h000000}; + 8'b00010000: swapped_data_i = {24'h000000, data_i[63:56], 32'h00000000}; + 8'b00100000: swapped_data_i = {16'h0000, data_i[63:56], 40'h0000000000}; + 8'b01000000: swapped_data_i = {8'h00, data_i[63:56], 48'h000000000000}; + 8'b10000000: swapped_data_i = {data_i[63:56], 56'h00000000000000}; + default: swapped_data_i = data_i; + endcase + else if (AXI_DATA_WIDTH == 32) + case (be_dec) + 4'b1111: swapped_data_i = data_i[63:32]; + 4'b0011: swapped_data_i = {16'h0000, data_i[63:48]}; + 4'b1100: swapped_data_i = {data_i[63:48], 16'h0000}; + 4'b0001: swapped_data_i = {24'h000000, data_i[63:56]}; + 4'b0010: swapped_data_i = {16'h0000, data_i[63:56], 8'h00}; + 4'b0100: swapped_data_i = {8'h00, data_i[63:56], 16'h0000}; + 4'b1000: swapped_data_i = {data_i[63:56], 24'h000000}; + default: swapped_data_i = data_i[63:32]; + endcase + generate + if (AXI_DATA_WIDTH == 64) begin : genblk1 + always @(*) + case (sel_reg) + 8'b00001111: swapped_data_out = axi_master_r_data; + 8'b11110000: swapped_data_out = {32'h00000000, axi_master_r_data[63:32]}; + 8'b00000011: swapped_data_out = axi_master_r_data; + 8'b00001100: swapped_data_out = {16'h0000, axi_master_r_data[63:16]}; + 8'b00110000: swapped_data_out = {32'h00000000, axi_master_r_data[63:32]}; + 8'b11000000: swapped_data_out = {48'h000000000000, axi_master_r_data[63:48]}; + 8'b00000001: swapped_data_out = axi_master_r_data; + 8'b00000010: swapped_data_out = {8'h00, axi_master_r_data[63:8]}; + 8'b00000100: swapped_data_out = {16'h0000, axi_master_r_data[63:16]}; + 8'b00001000: swapped_data_out = {24'h000000, axi_master_r_data[63:24]}; + 8'b00010000: swapped_data_out = {32'h00000000, axi_master_r_data[63:32]}; + 8'b00100000: swapped_data_out = {40'h0000000000, axi_master_r_data[63:40]}; + 8'b01000000: swapped_data_out = {48'h000000000000, axi_master_r_data[63:48]}; + 8'b10000000: swapped_data_out = {56'h00000000000000, axi_master_r_data[63:56]}; + default: swapped_data_out = axi_master_r_data; + endcase + end + else if (AXI_DATA_WIDTH == 32) begin : genblk1 + always @(*) + case (sel_reg) + 4'b1111: swapped_data_out = axi_master_r_data; + 4'b0011: swapped_data_out = axi_master_r_data; + 4'b1100: swapped_data_out = {16'h0000, axi_master_r_data[31:16]}; + 4'b0001: swapped_data_out = axi_master_r_data; + 4'b0010: swapped_data_out = {8'h00, axi_master_r_data[31:8]}; + 4'b0100: swapped_data_out = {16'h0000, axi_master_r_data[31:16]}; + 4'b1000: swapped_data_out = {24'h000000, axi_master_r_data[31:24]}; + default: swapped_data_out = axi_master_r_data; + endcase + end + endgenerate + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) begin + sel_reg <= 'h0; + addr_reg <= 'h0; + data_in_reg <= 'h0; + wr_reg <= 1'b0; + end + else if (strobe_i && rdy_o) begin + sel_reg <= be_dec; + addr_reg <= addr_i; + if (!rd_wrn_i) + data_in_reg <= swapped_data_i; + wr_reg <= ~rd_wrn_i; + end + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + str_sync <= 1'b0; + else if (strobe_i && rdy_o) + str_sync <= ~str_sync; + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) begin + rdy_sync_tff1 <= 1'b0; + rdy_sync_tff2 <= 1'b0; + rdy_sync_tff2q <= 1'b0; + end + else begin + rdy_sync_tff1 <= rdy_sync; + rdy_sync_tff2 <= rdy_sync_tff1; + rdy_sync_tff2q <= rdy_sync_tff2; + end + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + rdy_o <= 1'b1; + else if (strobe_i && rdy_o) + rdy_o <= 1'b0; + else if (rdy_sync_tff2 != rdy_sync_tff2q) + rdy_o <= 1'b1; + assign axi_master_ar_addr = addr_reg; + assign axi_master_aw_addr = addr_reg; + assign axi_master_w_data = data_in_reg; + assign axi_master_w_strb = sel_reg; + always @(*) + if (AXI_DATA_WIDTH == 64) + data_o = data_out_reg; + else if (AXI_DATA_WIDTH == 32) + data_o = {32'h00000000, data_out_reg}; + assign err_o = err_reg; + assign axi_master_aw_prot = 'h0; + assign axi_master_aw_region = 'h0; + assign axi_master_aw_len = 'h0; + assign axi_master_aw_burst = 'h0; + assign axi_master_aw_lock = 'h0; + assign axi_master_aw_cache = 'h0; + assign axi_master_aw_qos = 'h0; + assign axi_master_aw_id = 'h0; + assign axi_master_aw_user = 'h0; + assign axi_master_ar_prot = 'h0; + assign axi_master_ar_region = 'h0; + assign axi_master_ar_len = 'h0; + assign axi_master_ar_burst = 'h0; + assign axi_master_ar_lock = 'h0; + assign axi_master_ar_cache = 'h0; + assign axi_master_ar_qos = 'h0; + assign axi_master_ar_id = 'h0; + assign axi_master_ar_user = 'h0; + assign axi_master_w_user = 'h0; + assign axi_master_w_last = 1'b1; + always @(*) + case (word_size_i) + 4'h1: begin + axi_master_aw_size = 3'b000; + axi_master_ar_size = 3'b000; + end + 4'h2: begin + axi_master_aw_size = 3'b001; + axi_master_ar_size = 3'b001; + end + 4'h4: begin + axi_master_aw_size = 3'b010; + axi_master_ar_size = 3'b010; + end + 4'h8: begin + axi_master_aw_size = 3'b011; + axi_master_ar_size = 3'b011; + end + default: begin + axi_master_aw_size = 3'b011; + axi_master_ar_size = 3'b011; + end + endcase + always @(posedge axi_aclk or negedge axi_aresetn) + if (!axi_aresetn) begin + str_sync_wbff1 <= 1'b0; + str_sync_wbff2 <= 1'b0; + str_sync_wbff2q <= 1'b0; + end + else begin + str_sync_wbff1 <= str_sync; + str_sync_wbff2 <= str_sync_wbff1; + str_sync_wbff2q <= str_sync_wbff2; + end + assign start_toggle = str_sync_wbff2 != str_sync_wbff2q; + always @(posedge axi_aclk or negedge axi_aresetn) + if (!axi_aresetn) + err_reg <= 1'b0; + else if (err_en) + err_reg <= (wr_reg ? (axi_master_b_resp == 2'b00 ? 1'b0 : 1'b1) : (axi_master_r_resp == 2'b00 ? 1'b0 : 1'b1)); + always @(posedge axi_aclk or negedge axi_aresetn) + if (!axi_aresetn) + data_out_reg <= 32'h00000000; + else if (data_o_en) + data_out_reg <= swapped_data_out; + always @(posedge axi_aclk or negedge axi_aresetn) + if (!axi_aresetn) + rdy_sync <= 1'b0; + else if (rdy_sync_en) + rdy_sync <= ~rdy_sync; + always @(posedge axi_aclk or negedge axi_aresetn) + if (~axi_aresetn) + axi_fsm_state <= 2'd0; + else + axi_fsm_state <= next_fsm_state; + always @(*) begin + axi_master_aw_valid = 1'b0; + axi_master_w_valid = 1'b0; + axi_master_ar_valid = 1'b0; + axi_master_b_ready = 1'b0; + axi_master_r_ready = 1'b0; + next_fsm_state = axi_fsm_state; + rdy_sync_en = 1'b0; + data_o_en = 1'b0; + err_en = 1'b0; + case (axi_fsm_state) + 2'd0: + if (start_toggle) + next_fsm_state = 2'd1; + else + next_fsm_state = 2'd0; + 2'd1: begin + if (wr_reg) + axi_master_aw_valid = 1'b1; + else + axi_master_ar_valid = 1'b1; + if (wr_reg && axi_master_aw_ready) + next_fsm_state = 2'd2; + else if (!wr_reg && axi_master_ar_ready) + next_fsm_state = 2'd3; + end + 2'd2: begin + axi_master_w_valid = 1'b1; + if (axi_master_w_ready) + next_fsm_state = 2'd3; + end + 2'd3: begin + if (wr_reg) + axi_master_b_ready = 1'b1; + else + axi_master_r_ready = 1'b1; + if (wr_reg && axi_master_b_valid) begin + next_fsm_state = 2'd0; + rdy_sync_en = 1'b1; + err_en = 1'b1; + end + else if (!wr_reg && axi_master_r_valid) begin + data_o_en = 1'b1; + next_fsm_state = 2'd0; + rdy_sync_en = 1'b1; + err_en = 1'b1; + end + end + endcase + end +endmodule
diff --git a/verilog/rtl/ips/adv_dbg_if/rtl/adbg_axi_defines.v b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_axi_defines.v new file mode 100644 index 0000000..b9fe191 --- /dev/null +++ b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_axi_defines.v
@@ -0,0 +1,94 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// adbg_wb_defines.v //// +//// //// +//// //// +//// This file is part of the SoC Advanced Debug Interface. //// +//// //// +//// Author(s): //// +//// Nathan Yawn (nathan.yawn@opencores.org) //// +//// //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008-2010 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source 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 Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: adbg_wb_defines.v,v $ +// Revision 1.4 2010-01-10 22:54:11 Nathan +// Update copyright dates +// +// Revision 1.3 2009/05/17 20:54:57 Nathan +// Changed email address to opencores.org +// +// Revision 1.2 2009/05/04 00:50:11 Nathan +// Changed the AXI BIU to use big-endian byte ordering, to match the OR1000. Kept little-endian ordering as a compile-time option in case this is ever used with a little-endian CPU. +// +// Revision 1.1 2008/07/22 20:28:32 Nathan +// Changed names of all files and modules (prefixed an a, for advanced). Cleanup, indenting. No functional changes. +// + +// Endian-ness of the Wishbone interface. +// Default is BIG endian, to match the OR1200. +// If using a LITTLE endian CPU, e.g. an x86, un-comment this line. +//`define DBG_AXI_LITTLE_ENDIAN + +// These relate to the number of internal registers, and how +// many bits are required in the Reg. Select register +`define DBG_AXI_REGSELECT_SIZE 1 +`define DBG_AXI_NUM_INTREG 1 + +// Register index definitions for module-internal registers +// The AXI module has just 1, the error register +`define DBG_AXI_INTREG_ERROR 1'b0 + +// Valid commands/opcodes for the wishbone debug module +// 0000 NOP +// 0001 Write burst, 8-bit access +// 0010 Write burst, 16-bit access +// 0011 Write burst, 32-bit access +// 0100 Write burst, 64-bit access +// 0101 Read burst, 8-bit access +// 0110 Read burst, 16-bit access +// 0111 Read burst, 32-bit access +// 1000 Read burst, 64-bit access +// 1001 Internal register select/write +// 1010 - 1100 Reserved +// 1101 Internal register select +// 1110 - 1111 Reserved + +`define DBG_AXI_CMD_BWRITE8 4'h1 +`define DBG_AXI_CMD_BWRITE16 4'h2 +`define DBG_AXI_CMD_BWRITE32 4'h3 +`define DBG_AXI_CMD_BWRITE64 4'h4 +`define DBG_AXI_CMD_BREAD8 4'h5 +`define DBG_AXI_CMD_BREAD16 4'h6 +`define DBG_AXI_CMD_BREAD32 4'h7 +`define DBG_AXI_CMD_BREAD64 4'h8 +`define DBG_AXI_CMD_IREG_WR 4'h9 +`define DBG_AXI_CMD_IREG_SEL 4'hd
diff --git a/verilog/rtl/ips/adv_dbg_if/rtl/adbg_axi_module.v b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_axi_module.v new file mode 100644 index 0000000..bd65b3c --- /dev/null +++ b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_axi_module.v
@@ -0,0 +1,630 @@ +module adbg_axi_module +#( + parameter AXI_ADDR_WIDTH = 32, + parameter AXI_DATA_WIDTH = 64, + parameter AXI_USER_WIDTH = 6, + parameter AXI_ID_WIDTH = 3 +) +( + tck_i, + module_tdo_o, + tdi_i, + capture_dr_i, + shift_dr_i, + update_dr_i, + data_register_i, + module_select_i, + top_inhibit_o, + trstn_i, + axi_aclk, + axi_aresetn, + axi_master_aw_valid, + axi_master_aw_addr, + axi_master_aw_prot, + axi_master_aw_region, + axi_master_aw_len, + axi_master_aw_size, + axi_master_aw_burst, + axi_master_aw_lock, + axi_master_aw_cache, + axi_master_aw_qos, + axi_master_aw_id, + axi_master_aw_user, + axi_master_aw_ready, + axi_master_ar_valid, + axi_master_ar_addr, + axi_master_ar_prot, + axi_master_ar_region, + axi_master_ar_len, + axi_master_ar_size, + axi_master_ar_burst, + axi_master_ar_lock, + axi_master_ar_cache, + axi_master_ar_qos, + axi_master_ar_id, + axi_master_ar_user, + axi_master_ar_ready, + axi_master_w_valid, + axi_master_w_data, + axi_master_w_strb, + axi_master_w_user, + axi_master_w_last, + axi_master_w_ready, + axi_master_r_valid, + axi_master_r_data, + axi_master_r_resp, + axi_master_r_last, + axi_master_r_id, + axi_master_r_user, + axi_master_r_ready, + axi_master_b_valid, + axi_master_b_resp, + axi_master_b_id, + axi_master_b_user, + axi_master_b_ready +); + //parameter AXI_ADDR_WIDTH = 32; + //parameter AXI_DATA_WIDTH = 64; + //parameter AXI_USER_WIDTH = 6; + //parameter AXI_ID_WIDTH = 3; + input wire tck_i; + output reg module_tdo_o; + input wire tdi_i; + input wire capture_dr_i; + input wire shift_dr_i; + input wire update_dr_i; + input wire [63:0] data_register_i; + input wire module_select_i; + output reg top_inhibit_o; + input wire trstn_i; + input wire axi_aclk; + input wire axi_aresetn; + output wire axi_master_aw_valid; + output wire [AXI_ADDR_WIDTH - 1:0] axi_master_aw_addr; + output wire [2:0] axi_master_aw_prot; + output wire [3:0] axi_master_aw_region; + output wire [7:0] axi_master_aw_len; + output wire [2:0] axi_master_aw_size; + output wire [1:0] axi_master_aw_burst; + output wire axi_master_aw_lock; + output wire [3:0] axi_master_aw_cache; + output wire [3:0] axi_master_aw_qos; + output wire [AXI_ID_WIDTH - 1:0] axi_master_aw_id; + output wire [AXI_USER_WIDTH - 1:0] axi_master_aw_user; + input wire axi_master_aw_ready; + output wire axi_master_ar_valid; + output wire [AXI_ADDR_WIDTH - 1:0] axi_master_ar_addr; + output wire [2:0] axi_master_ar_prot; + output wire [3:0] axi_master_ar_region; + output wire [7:0] axi_master_ar_len; + output wire [2:0] axi_master_ar_size; + output wire [1:0] axi_master_ar_burst; + output wire axi_master_ar_lock; + output wire [3:0] axi_master_ar_cache; + output wire [3:0] axi_master_ar_qos; + output wire [AXI_ID_WIDTH - 1:0] axi_master_ar_id; + output wire [AXI_USER_WIDTH - 1:0] axi_master_ar_user; + input wire axi_master_ar_ready; + output wire axi_master_w_valid; + output wire [AXI_DATA_WIDTH - 1:0] axi_master_w_data; + output wire [(AXI_DATA_WIDTH / 8) - 1:0] axi_master_w_strb; + output wire [AXI_USER_WIDTH - 1:0] axi_master_w_user; + output wire axi_master_w_last; + input wire axi_master_w_ready; + input wire axi_master_r_valid; + input wire [AXI_DATA_WIDTH - 1:0] axi_master_r_data; + input wire [1:0] axi_master_r_resp; + input wire axi_master_r_last; + input wire [AXI_ID_WIDTH - 1:0] axi_master_r_id; + input wire [AXI_USER_WIDTH - 1:0] axi_master_r_user; + output wire axi_master_r_ready; + input wire axi_master_b_valid; + input wire [1:0] axi_master_b_resp; + input wire [AXI_ID_WIDTH - 1:0] axi_master_b_id; + input wire [AXI_USER_WIDTH - 1:0] axi_master_b_user; + output wire axi_master_b_ready; + reg [31:0] address_counter; + reg [5:0] bit_count; + reg [15:0] word_count; + reg [3:0] operation; + reg [64:0] data_out_shift_reg; + reg [0:0] internal_register_select; + reg [32:0] internal_reg_error; + reg addr_sel; + reg addr_ct_en; + reg op_reg_en; + reg bit_ct_en; + reg bit_ct_rst; + reg word_ct_sel; + reg word_ct_en; + reg out_reg_ld_en; + reg out_reg_shift_en; + reg out_reg_data_sel; + reg [1:0] tdo_output_sel; + reg biu_strobe; + reg crc_clr; + reg crc_en; + reg crc_in_sel; + reg crc_shift_en; + reg regsel_ld_en; + reg intreg_ld_en; + reg error_reg_en; + reg biu_clr_err; + wire word_count_zero; + wire bit_count_max; + wire module_cmd; + wire biu_ready; + wire biu_err; + wire burst_read; + wire burst_write; + wire intreg_instruction; + wire intreg_write; + reg rd_op; + wire crc_match; + wire bit_count_32; + reg [5:0] word_size_bits; + reg [3:0] word_size_bytes; + wire [32:0] incremented_address; + wire [31:0] data_to_addr_counter; + wire [15:0] data_to_word_counter; + wire [15:0] decremented_word_count; + wire [31:0] address_data_in; + wire [15:0] count_data_in; + wire [3:0] operation_in; + wire [63:0] data_to_biu; + wire [63:0] data_from_biu; + wire [31:0] crc_data_out; + wire crc_data_in; + wire crc_serial_out; + wire [0:0] reg_select_data; + wire [64:0] out_reg_data; + reg [64:0] data_from_internal_reg; + wire biu_rst; + reg [3:0] module_state; + reg [3:0] module_next_state; + assign module_cmd = ~data_register_i[63]; + assign operation_in = data_register_i[62:59]; + assign address_data_in = data_register_i[58:27]; + assign count_data_in = data_register_i[26:11]; + assign data_to_biu = {tdi_i, data_register_i[63:1]}; + assign reg_select_data = data_register_i[58:57]; + assign intreg_instruction = (operation_in == 4'h9) | (operation_in == 4'hd); + assign intreg_write = operation_in == 4'h9; + assign burst_write = (((operation_in == 4'h1) | (operation_in == 4'h2)) | (operation_in == 4'h3)) | (operation_in == 4'h4); + assign burst_read = (((operation_in == 4'h5) | (operation_in == 4'h6)) | (operation_in == 4'h7)) | (operation_in == 4'h8); + always @(*) + case (operation) + 4'h1: begin + word_size_bits = 6'd7; + word_size_bytes = 4'd1; + rd_op = 1'b0; + end + 4'h2: begin + word_size_bits = 6'd15; + word_size_bytes = 4'd2; + rd_op = 1'b0; + end + 4'h3: begin + word_size_bits = 6'd31; + word_size_bytes = 4'd4; + rd_op = 1'b0; + end + 4'h4: begin + word_size_bits = 6'd63; + word_size_bytes = 4'd8; + rd_op = 1'b0; + end + 4'h5: begin + word_size_bits = 6'd7; + word_size_bytes = 4'd1; + rd_op = 1'b1; + end + 4'h6: begin + word_size_bits = 6'd15; + word_size_bytes = 4'd2; + rd_op = 1'b1; + end + 4'h7: begin + word_size_bits = 6'd31; + word_size_bytes = 4'd4; + rd_op = 1'b1; + end + 4'h8: begin + word_size_bits = 6'd63; + word_size_bytes = 4'd4; + rd_op = 1'b1; + end + default: begin + word_size_bits = 6'b000000; + word_size_bytes = 4'b0000; + rd_op = 1'b0; + end + endcase + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + internal_register_select <= 1'h0; + else if (regsel_ld_en) + internal_register_select <= reg_select_data; + always @(*) + case (internal_register_select) + 1'b0: data_from_internal_reg = internal_reg_error; + default: data_from_internal_reg = internal_reg_error; + endcase + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + internal_reg_error <= 33'h000000000; + else if (intreg_ld_en && (reg_select_data == 1'b0)) begin + if (data_register_i[46]) + internal_reg_error[0] <= 1'b0; + end + else if (error_reg_en && !internal_reg_error[0]) begin + if (biu_err || !biu_ready) + internal_reg_error[0] <= 1'b1; + else if (biu_strobe) + internal_reg_error[32:1] <= address_counter; + end + else if (biu_strobe && !internal_reg_error[0]) + internal_reg_error[32:1] <= address_counter; + assign data_to_addr_counter = (addr_sel ? incremented_address[31:0] : address_data_in); + assign incremented_address = address_counter + word_size_bytes; + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + address_counter <= 32'h00000000; + else if (addr_ct_en) + address_counter <= data_to_addr_counter; + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + operation <= 4'h0; + else if (op_reg_en) + operation <= operation_in; + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + bit_count <= 6'h00; + else if (bit_ct_rst) + bit_count <= 6'h00; + else if (bit_ct_en) + bit_count <= bit_count + 6'h01; + assign bit_count_max = (bit_count == word_size_bits ? 1'b1 : 1'b0); + assign bit_count_32 = (bit_count == 6'h20 ? 1'b1 : 1'b0); + assign data_to_word_counter = (word_ct_sel ? decremented_word_count : count_data_in); + assign decremented_word_count = word_count - 16'h0001; + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + word_count <= 16'h0000; + else if (word_ct_en) + word_count <= data_to_word_counter; + assign word_count_zero = word_count == 16'h0000; + assign out_reg_data = (out_reg_data_sel ? data_from_internal_reg : {1'b0, data_from_biu}); + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + data_out_shift_reg <= 'h0; + else if (out_reg_ld_en) + data_out_shift_reg <= out_reg_data; + else if (out_reg_shift_en) + data_out_shift_reg <= {1'b0, data_out_shift_reg[64:1]}; + always @(*) + if (tdo_output_sel == 2'h0) + module_tdo_o = biu_ready; + else if (tdo_output_sel == 2'h1) + module_tdo_o = data_out_shift_reg[0]; + else if (tdo_output_sel == 2'h2) + module_tdo_o = crc_match; + else + module_tdo_o = crc_serial_out; + adbg_axi_biu #( + .AXI_ADDR_WIDTH(AXI_ADDR_WIDTH), + .AXI_DATA_WIDTH(AXI_DATA_WIDTH), + .AXI_USER_WIDTH(AXI_USER_WIDTH), + .AXI_ID_WIDTH(AXI_ID_WIDTH) + ) axi_biu_i( + .tck_i(tck_i), + .trstn_i(trstn_i), + .data_i(data_to_biu), + .data_o(data_from_biu), + .addr_i(address_counter), + .strobe_i(biu_strobe), + .rd_wrn_i(rd_op), + .rdy_o(biu_ready), + .err_o(biu_err), + .word_size_i(word_size_bytes), + .axi_aclk(axi_aclk), + .axi_aresetn(axi_aresetn), + .axi_master_aw_valid(axi_master_aw_valid), + .axi_master_aw_addr(axi_master_aw_addr), + .axi_master_aw_prot(axi_master_aw_prot), + .axi_master_aw_region(axi_master_aw_region), + .axi_master_aw_len(axi_master_aw_len), + .axi_master_aw_size(axi_master_aw_size), + .axi_master_aw_burst(axi_master_aw_burst), + .axi_master_aw_lock(axi_master_aw_lock), + .axi_master_aw_cache(axi_master_aw_cache), + .axi_master_aw_qos(axi_master_aw_qos), + .axi_master_aw_id(axi_master_aw_id), + .axi_master_aw_user(axi_master_aw_user), + .axi_master_aw_ready(axi_master_aw_ready), + .axi_master_ar_valid(axi_master_ar_valid), + .axi_master_ar_addr(axi_master_ar_addr), + .axi_master_ar_prot(axi_master_ar_prot), + .axi_master_ar_region(axi_master_ar_region), + .axi_master_ar_len(axi_master_ar_len), + .axi_master_ar_size(axi_master_ar_size), + .axi_master_ar_burst(axi_master_ar_burst), + .axi_master_ar_lock(axi_master_ar_lock), + .axi_master_ar_cache(axi_master_ar_cache), + .axi_master_ar_qos(axi_master_ar_qos), + .axi_master_ar_id(axi_master_ar_id), + .axi_master_ar_user(axi_master_ar_user), + .axi_master_ar_ready(axi_master_ar_ready), + .axi_master_w_valid(axi_master_w_valid), + .axi_master_w_data(axi_master_w_data), + .axi_master_w_strb(axi_master_w_strb), + .axi_master_w_user(axi_master_w_user), + .axi_master_w_last(axi_master_w_last), + .axi_master_w_ready(axi_master_w_ready), + .axi_master_r_valid(axi_master_r_valid), + .axi_master_r_data(axi_master_r_data), + .axi_master_r_resp(axi_master_r_resp), + .axi_master_r_last(axi_master_r_last), + .axi_master_r_id(axi_master_r_id), + .axi_master_r_user(axi_master_r_user), + .axi_master_r_ready(axi_master_r_ready), + .axi_master_b_valid(axi_master_b_valid), + .axi_master_b_resp(axi_master_b_resp), + .axi_master_b_id(axi_master_b_id), + .axi_master_b_user(axi_master_b_user), + .axi_master_b_ready(axi_master_b_ready) + ); + assign crc_data_in = (crc_in_sel ? tdi_i : data_out_shift_reg[0]); + adbg_crc32 axi_crc_i( + .clk(tck_i), + .data(crc_data_in), + .enable(crc_en), + .shift(crc_shift_en), + .clr(crc_clr), + .rstn(trstn_i), + .crc_out(crc_data_out), + .serial_out(crc_serial_out) + ); + assign crc_match = (data_register_i[63:32] == crc_data_out ? 1'b1 : 1'b0); + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + module_state <= 4'd0; + else + module_state <= module_next_state; + always @(*) + case (module_state) + 4'd0: + if (((module_cmd && module_select_i) && update_dr_i) && burst_read) + module_next_state = 4'd1; + else if (((module_cmd && module_select_i) && update_dr_i) && burst_write) + module_next_state = 4'd5; + else + module_next_state = 4'd0; + 4'd1: + if (word_count_zero) + module_next_state = 4'd0; + else + module_next_state = 4'd2; + 4'd2: + if (module_select_i && capture_dr_i) + module_next_state = 4'd3; + else + module_next_state = 4'd2; + 4'd3: + if (update_dr_i) + module_next_state = 4'd0; + else if (biu_ready) + module_next_state = 4'd4; + else + module_next_state = 4'd3; + 4'd4: + if (update_dr_i) + module_next_state = 4'd0; + else if (bit_count_max && word_count_zero) + module_next_state = 4'd9; + else + module_next_state = 4'd4; + 4'd9: + if (update_dr_i) + module_next_state = 4'd0; + else + module_next_state = 4'd9; + 4'd5: + if (word_count_zero) + module_next_state = 4'd0; + else if (module_select_i && capture_dr_i) + module_next_state = 4'd6; + else + module_next_state = 4'd5; + 4'd6: + if (update_dr_i) + module_next_state = 4'd0; + else if (module_select_i && data_register_i[63]) + module_next_state = 4'd7; + else + module_next_state = 4'd6; + 4'd7: + if (update_dr_i) + module_next_state = 4'd0; + else if (bit_count_max) begin + if (word_count_zero) + module_next_state = 4'd10; + else + module_next_state = 4'd7; + end + else + module_next_state = 4'd7; + 4'd8: + if (update_dr_i) + module_next_state = 4'd0; + else if (word_count_zero) + module_next_state = 4'd10; + else + module_next_state = 4'd7; + 4'd10: + if (update_dr_i) + module_next_state = 4'd0; + else if (bit_count_32) + module_next_state = 4'd11; + else + module_next_state = 4'd10; + 4'd11: + if (update_dr_i) + module_next_state = 4'd0; + else + module_next_state = 4'd11; + default: module_next_state = 4'd0; + endcase + always @(*) begin + addr_sel = 1'b1; + addr_ct_en = 1'b0; + op_reg_en = 1'b0; + bit_ct_en = 1'b0; + bit_ct_rst = 1'b0; + word_ct_sel = 1'b1; + word_ct_en = 1'b0; + out_reg_ld_en = 1'b0; + out_reg_shift_en = 1'b0; + tdo_output_sel = 2'b01; + biu_strobe = 1'b0; + crc_clr = 1'b0; + crc_en = 1'b0; + crc_in_sel = 1'b0; + crc_shift_en = 1'b0; + out_reg_data_sel = 1'b1; + regsel_ld_en = 1'b0; + intreg_ld_en = 1'b0; + error_reg_en = 1'b0; + biu_clr_err = 1'b0; + top_inhibit_o = 1'b0; + case (module_state) + 4'd0: begin + addr_sel = 1'b0; + word_ct_sel = 1'b0; + if (module_select_i & shift_dr_i) + out_reg_shift_en = 1'b1; + if (module_select_i & capture_dr_i) begin + out_reg_data_sel = 1'b1; + out_reg_ld_en = 1'b1; + end + if ((module_select_i & module_cmd) & update_dr_i) begin + if (intreg_instruction) + regsel_ld_en = 1'b1; + if (intreg_write) + intreg_ld_en = 1'b1; + end + if (module_next_state != 4'd0) begin + addr_ct_en = 1'b1; + op_reg_en = 1'b1; + bit_ct_rst = 1'b1; + word_ct_en = 1'b1; + crc_clr = 1'b1; + end + end + 4'd1: + if (!word_count_zero) begin + biu_strobe = 1'b1; + addr_sel = 1'b1; + addr_ct_en = 1'b1; + end + 4'd2: + ; + 4'd3: begin + tdo_output_sel = 2'h0; + top_inhibit_o = 1'b1; + if (module_next_state == 4'd4) begin + error_reg_en = 1'b1; + out_reg_data_sel = 1'b0; + out_reg_ld_en = 1'b1; + bit_ct_rst = 1'b1; + word_ct_sel = 1'b1; + word_ct_en = 1'b1; + if ((decremented_word_count != 0) && !word_count_zero) begin + biu_strobe = 1'b1; + addr_sel = 1'b1; + addr_ct_en = 1'b1; + end + end + end + 4'd4: begin + tdo_output_sel = 2'h1; + out_reg_shift_en = 1'b1; + bit_ct_en = 1'b1; + crc_en = 1'b1; + crc_in_sel = 1'b0; + top_inhibit_o = 1'b1; + if (bit_count_max) begin + error_reg_en = 1'b1; + out_reg_data_sel = 1'b0; + out_reg_ld_en = 1'b1; + bit_ct_rst = 1'b1; + word_ct_sel = 1'b1; + word_ct_en = 1'b1; + if ((decremented_word_count != 0) && !word_count_zero) begin + biu_strobe = 1'b1; + addr_sel = 1'b1; + addr_ct_en = 1'b1; + end + end + end + 4'd9: begin + tdo_output_sel = 2'h3; + crc_shift_en = 1'b1; + top_inhibit_o = 1'b1; + end + 4'd5: + ; + 4'd6: begin + tdo_output_sel = 2'h1; + top_inhibit_o = 1'b1; + if (module_next_state == 4'd7) begin + biu_clr_err = 1'b1; + bit_ct_en = 1'b1; + word_ct_sel = 1'b1; + word_ct_en = 1'b1; + crc_en = 1'b1; + crc_in_sel = 1'b1; + end + end + 4'd7: begin + bit_ct_en = 1'b1; + tdo_output_sel = 2'h1; + crc_en = 1'b1; + crc_in_sel = 1'b1; + top_inhibit_o = 1'b1; + if (bit_count_max) begin + error_reg_en = 1'b1; + bit_ct_rst = 1'b1; + biu_strobe = 1'b1; + addr_ct_en = 1'b1; + word_ct_sel = 1'b1; + word_ct_en = 1'b1; + end + end + 4'd8: begin + tdo_output_sel = 2'h0; + error_reg_en = 1'b1; + biu_strobe = 1'b1; + word_ct_sel = 1'b1; + word_ct_en = 1'b1; + bit_ct_rst = 1'b1; + addr_ct_en = 1'b1; + top_inhibit_o = 1'b1; + end + 4'd10: begin + bit_ct_en = 1'b1; + top_inhibit_o = 1'b1; + if (module_next_state == 4'd11) + tdo_output_sel = 2'h2; + end + 4'd11: begin + tdo_output_sel = 2'h2; + top_inhibit_o = 1'b1; + if (module_next_state == 4'd0) + error_reg_en = 1'b1; + end + default: + ; + endcase + end +endmodule
diff --git a/verilog/rtl/ips/adv_dbg_if/rtl/adbg_axionly_top.v b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_axionly_top.v new file mode 100644 index 0000000..11ab4dc --- /dev/null +++ b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_axionly_top.v
@@ -0,0 +1,225 @@ +module adbg_axionly_top +#( + parameter NB_CORES = 4, + parameter AXI_ADDR_WIDTH = 32, + parameter AXI_DATA_WIDTH = 64, + parameter AXI_USER_WIDTH = 6, + parameter AXI_ID_WIDTH = 3 +) +( + tck_i, + tdi_i, + tdo_o, + trstn_i, + shift_dr_i, + pause_dr_i, + update_dr_i, + capture_dr_i, + debug_select_i, + axi_aclk, + axi_aresetn, + axi_master_aw_valid, + axi_master_aw_addr, + axi_master_aw_prot, + axi_master_aw_region, + axi_master_aw_len, + axi_master_aw_size, + axi_master_aw_burst, + axi_master_aw_lock, + axi_master_aw_cache, + axi_master_aw_qos, + axi_master_aw_id, + axi_master_aw_user, + axi_master_aw_ready, + axi_master_ar_valid, + axi_master_ar_addr, + axi_master_ar_prot, + axi_master_ar_region, + axi_master_ar_len, + axi_master_ar_size, + axi_master_ar_burst, + axi_master_ar_lock, + axi_master_ar_cache, + axi_master_ar_qos, + axi_master_ar_id, + axi_master_ar_user, + axi_master_ar_ready, + axi_master_w_valid, + axi_master_w_data, + axi_master_w_strb, + axi_master_w_user, + axi_master_w_last, + axi_master_w_ready, + axi_master_r_valid, + axi_master_r_data, + axi_master_r_resp, + axi_master_r_last, + axi_master_r_id, + axi_master_r_user, + axi_master_r_ready, + axi_master_b_valid, + axi_master_b_resp, + axi_master_b_id, + axi_master_b_user, + axi_master_b_ready +); + //parameter NB_CORES = 4; + //parameter AXI_ADDR_WIDTH = 32; + //parameter AXI_DATA_WIDTH = 64; + //parameter AXI_USER_WIDTH = 6; + //parameter AXI_ID_WIDTH = 3; + input wire tck_i; + input wire tdi_i; + output reg tdo_o; + input wire trstn_i; + input wire shift_dr_i; + input wire pause_dr_i; + input wire update_dr_i; + input wire capture_dr_i; + input wire debug_select_i; + input wire axi_aclk; + input wire axi_aresetn; + output wire axi_master_aw_valid; + output wire [AXI_ADDR_WIDTH - 1:0] axi_master_aw_addr; + output wire [2:0] axi_master_aw_prot; + output wire [3:0] axi_master_aw_region; + output wire [7:0] axi_master_aw_len; + output wire [2:0] axi_master_aw_size; + output wire [1:0] axi_master_aw_burst; + output wire axi_master_aw_lock; + output wire [3:0] axi_master_aw_cache; + output wire [3:0] axi_master_aw_qos; + output wire [AXI_ID_WIDTH - 1:0] axi_master_aw_id; + output wire [AXI_USER_WIDTH - 1:0] axi_master_aw_user; + input wire axi_master_aw_ready; + output wire axi_master_ar_valid; + output wire [AXI_ADDR_WIDTH - 1:0] axi_master_ar_addr; + output wire [2:0] axi_master_ar_prot; + output wire [3:0] axi_master_ar_region; + output wire [7:0] axi_master_ar_len; + output wire [2:0] axi_master_ar_size; + output wire [1:0] axi_master_ar_burst; + output wire axi_master_ar_lock; + output wire [3:0] axi_master_ar_cache; + output wire [3:0] axi_master_ar_qos; + output wire [AXI_ID_WIDTH - 1:0] axi_master_ar_id; + output wire [AXI_USER_WIDTH - 1:0] axi_master_ar_user; + input wire axi_master_ar_ready; + output wire axi_master_w_valid; + output wire [AXI_DATA_WIDTH - 1:0] axi_master_w_data; + output wire [(AXI_DATA_WIDTH / 8) - 1:0] axi_master_w_strb; + output wire [AXI_USER_WIDTH - 1:0] axi_master_w_user; + output wire axi_master_w_last; + input wire axi_master_w_ready; + input wire axi_master_r_valid; + input wire [AXI_DATA_WIDTH - 1:0] axi_master_r_data; + input wire [1:0] axi_master_r_resp; + input wire axi_master_r_last; + input wire [AXI_ID_WIDTH - 1:0] axi_master_r_id; + input wire [AXI_USER_WIDTH - 1:0] axi_master_r_user; + output wire axi_master_r_ready; + input wire axi_master_b_valid; + input wire [1:0] axi_master_b_resp; + input wire [AXI_ID_WIDTH - 1:0] axi_master_b_id; + input wire [AXI_USER_WIDTH - 1:0] axi_master_b_user; + output wire axi_master_b_ready; + wire tdo_axi; + wire tdo_cpu; + reg [63:0] input_shift_reg; + reg [4:0] module_id_reg; + wire select_cmd; + wire [4:0] module_id_in; + reg [1:0] module_selects; + wire select_inhibit; + wire [1:0] module_inhibit; + integer j; + assign tdo_cpu = 1'b0; + assign select_cmd = input_shift_reg[63]; + assign module_id_in = input_shift_reg[62:58]; + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + module_id_reg <= 5'h00; + else if (((debug_select_i && select_cmd) && update_dr_i) && !select_inhibit) + module_id_reg <= module_id_in; + always @(*) + if (module_id_reg == 0) + module_selects = 2'b01; + else + module_selects = 2'b10; + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + input_shift_reg <= 'h0; + else if (debug_select_i && shift_dr_i) + input_shift_reg <= {tdi_i, input_shift_reg[63:1]}; + adbg_axi_module #( + .AXI_ADDR_WIDTH(AXI_ADDR_WIDTH), + .AXI_DATA_WIDTH(AXI_DATA_WIDTH), + .AXI_USER_WIDTH(AXI_USER_WIDTH), + .AXI_ID_WIDTH(AXI_ID_WIDTH) + ) i_dbg_axi( + .tck_i(tck_i), + .module_tdo_o(tdo_axi), + .tdi_i(tdi_i), + .capture_dr_i(capture_dr_i), + .shift_dr_i(shift_dr_i), + .update_dr_i(update_dr_i), + .data_register_i(input_shift_reg), + .module_select_i(module_selects[0]), + .top_inhibit_o(module_inhibit[0]), + .trstn_i(trstn_i), + .axi_aclk(axi_aclk), + .axi_aresetn(axi_aresetn), + .axi_master_aw_valid(axi_master_aw_valid), + .axi_master_aw_addr(axi_master_aw_addr), + .axi_master_aw_prot(axi_master_aw_prot), + .axi_master_aw_region(axi_master_aw_region), + .axi_master_aw_len(axi_master_aw_len), + .axi_master_aw_size(axi_master_aw_size), + .axi_master_aw_burst(axi_master_aw_burst), + .axi_master_aw_lock(axi_master_aw_lock), + .axi_master_aw_cache(axi_master_aw_cache), + .axi_master_aw_qos(axi_master_aw_qos), + .axi_master_aw_id(axi_master_aw_id), + .axi_master_aw_user(axi_master_aw_user), + .axi_master_aw_ready(axi_master_aw_ready), + .axi_master_ar_valid(axi_master_ar_valid), + .axi_master_ar_addr(axi_master_ar_addr), + .axi_master_ar_prot(axi_master_ar_prot), + .axi_master_ar_region(axi_master_ar_region), + .axi_master_ar_len(axi_master_ar_len), + .axi_master_ar_size(axi_master_ar_size), + .axi_master_ar_burst(axi_master_ar_burst), + .axi_master_ar_lock(axi_master_ar_lock), + .axi_master_ar_cache(axi_master_ar_cache), + .axi_master_ar_qos(axi_master_ar_qos), + .axi_master_ar_id(axi_master_ar_id), + .axi_master_ar_user(axi_master_ar_user), + .axi_master_ar_ready(axi_master_ar_ready), + .axi_master_w_valid(axi_master_w_valid), + .axi_master_w_data(axi_master_w_data), + .axi_master_w_strb(axi_master_w_strb), + .axi_master_w_user(axi_master_w_user), + .axi_master_w_last(axi_master_w_last), + .axi_master_w_ready(axi_master_w_ready), + .axi_master_r_valid(axi_master_r_valid), + .axi_master_r_data(axi_master_r_data), + .axi_master_r_resp(axi_master_r_resp), + .axi_master_r_last(axi_master_r_last), + .axi_master_r_id(axi_master_r_id), + .axi_master_r_user(axi_master_r_user), + .axi_master_r_ready(axi_master_r_ready), + .axi_master_b_valid(axi_master_b_valid), + .axi_master_b_resp(axi_master_b_resp), + .axi_master_b_id(axi_master_b_id), + .axi_master_b_user(axi_master_b_user), + .axi_master_b_ready(axi_master_b_ready) + ); + assign select_inhibit = |module_inhibit; + always @(*) + if (module_id_reg == 0) + tdo_o = tdo_axi; + else if (module_id_reg == 1) + tdo_o = tdo_cpu; + else + tdo_o = 1'b0; +endmodule
diff --git a/verilog/rtl/ips/adv_dbg_if/rtl/adbg_crc32.v b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_crc32.v new file mode 100644 index 0000000..6e04790 --- /dev/null +++ b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_crc32.v
@@ -0,0 +1,121 @@ +////////////////////////////////////////////////////////////////////// +// File: CRC32.v +// Date: Thu Nov 27 13:56:49 2003 +// +// Copyright (C) 1999-2003 Easics NV. +// This source file may be used and distributed without restriction +// provided that this copyright statement is not removed from the file +// and that any derivative work contains the original copyright notice +// and the associated disclaimer. +// +// THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS +// OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +// WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Purpose: Verilog module containing a synthesizable CRC function +// * polynomial: (0 1 2 4 5 7 8 10 11 12 16 22 23 26 32) +// * data width: 1 +// +// Info: janz@easics.be (Jan Zegers) +// http://www.easics.com +// +// Modified by Nathan Yawn for the Advanced Debug Module +// Changes (C) 2008 - 2010 Nathan Yawn +/////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: adbg_crc32.v,v $ +// Revision 1.3 2011-10-24 02:25:11 natey +// Removed extraneous '#1' delays, which were a holdover from the original +// versions in the previous dbg_if core. +// +// Revision 1.2 2010-01-10 22:54:10 Nathan +// Update copyright dates +// +// Revision 1.1 2008/07/22 20:28:29 Nathan +// Changed names of all files and modules (prefixed an a, for advanced). Cleanup, indenting. No functional changes. +// +// Revision 1.3 2008/07/06 20:02:53 Nathan +// Fixes for synthesis with Xilinx ISE (also synthesizable with +// Quartus II 7.0). Ran through dos2unix. +// +// Revision 1.2 2008/06/20 19:22:10 Nathan +// Reversed the direction of the CRC computation shift, for a more +// hardware-efficient implementation. +// +// +// +// + + +module adbg_crc32 (clk, data, enable, shift, clr, rstn, crc_out, serial_out); + +input clk; +input data; +input enable; +input shift; +input clr; +input rstn; +output [31:0] crc_out; +output serial_out; + + +reg [31:0] crc; +wire [31:0] new_crc; + + +// You may notice that the 'poly' in this implementation is backwards. +// This is because the shift is also 'backwards', so that the data can +// be shifted out in the same direction, which saves on logic + routing. +assign new_crc[0] = crc[1]; +assign new_crc[1] = crc[2]; +assign new_crc[2] = crc[3]; +assign new_crc[3] = crc[4]; +assign new_crc[4] = crc[5]; +assign new_crc[5] = crc[6] ^ data ^ crc[0]; +assign new_crc[6] = crc[7]; +assign new_crc[7] = crc[8]; +assign new_crc[8] = crc[9] ^ data ^ crc[0]; +assign new_crc[9] = crc[10] ^ data ^ crc[0]; +assign new_crc[10] = crc[11]; +assign new_crc[11] = crc[12]; +assign new_crc[12] = crc[13]; +assign new_crc[13] = crc[14]; +assign new_crc[14] = crc[15]; +assign new_crc[15] = crc[16] ^ data ^ crc[0]; +assign new_crc[16] = crc[17]; +assign new_crc[17] = crc[18]; +assign new_crc[18] = crc[19]; +assign new_crc[19] = crc[20] ^ data ^ crc[0]; +assign new_crc[20] = crc[21] ^ data ^ crc[0]; +assign new_crc[21] = crc[22] ^ data ^ crc[0]; +assign new_crc[22] = crc[23]; +assign new_crc[23] = crc[24] ^ data ^ crc[0]; +assign new_crc[24] = crc[25] ^ data ^ crc[0]; +assign new_crc[25] = crc[26]; +assign new_crc[26] = crc[27] ^ data ^ crc[0]; +assign new_crc[27] = crc[28] ^ data ^ crc[0]; +assign new_crc[28] = crc[29]; +assign new_crc[29] = crc[30] ^ data ^ crc[0]; +assign new_crc[30] = crc[31] ^ data ^ crc[0]; +assign new_crc[31] = data ^ crc[0]; + +always @ (posedge clk or negedge rstn) +begin + if(~rstn) + crc[31:0] <= 32'hffffffff; + else if(clr) + crc[31:0] <= 32'hffffffff; + else if(enable) + crc[31:0] <= new_crc; + else if (shift) + crc[31:0] <= {1'b0, crc[31:1]}; +end + + +//assign crc_match = (crc == 32'h0); +assign crc_out = crc; //[31]; +assign serial_out = crc[0]; + +endmodule
diff --git a/verilog/rtl/ips/adv_dbg_if/rtl/adbg_defines.v b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_defines.v new file mode 100644 index 0000000..0644ea0 --- /dev/null +++ b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_defines.v
@@ -0,0 +1,75 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// adbg_defines.v //// +//// //// +//// //// +//// This file is part of the Advanced Debug Interface. //// +//// //// +//// Author(s): //// +//// Nathan Yawn (nathan.yawn@opencores.org) //// +//// //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008 - 2010 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source 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 Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// + + +// Length of the MODULE ID register +`define DBG_TOP_MODULE_ID_LENGTH 2 + +// How many modules can be supported by the module id length +`define DBG_TOP_MAX_MODULES 4 + +// Chains +`define DBG_TOP_WISHBONE_DEBUG_MODULE 2'h0 +`define DBG_TOP_CPU0_DEBUG_MODULE 2'h1 +`define DBG_TOP_CPU1_DEBUG_MODULE 2'h2 +`define DBG_TOP_JSP_DEBUG_MODULE 2'h3 + +// Length of data +`define DBG_TOP_MODULE_DATA_LEN 64 + + +// If WISHBONE sub-module is supported uncomment the following line +`define DBG_WISHBONE_SUPPORTED + +// If CPU_0 sub-module is supported uncomment the following line +`define DBG_CPU0_SUPPORTED + +// If CPU_1 sub-module is supported uncomment the following line +//`define DBG_CPU1_SUPPORTED + +// To include the JTAG Serial Port (JSP), uncomment the following line +`define DBG_JSP_SUPPORTED + +// Define this if you intend to use the JSP in a system with multiple +// devices on the JTAG chain +`define ADBG_JSP_SUPPORT_MULTI + +// If this is defined, status bits will be skipped on burst +// reads and writes to improve download speeds. +`define ADBG_USE_HISPEED
diff --git a/verilog/rtl/ips/adv_dbg_if/rtl/adbg_lint_biu.v b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_lint_biu.v new file mode 100644 index 0000000..b778f70 --- /dev/null +++ b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_lint_biu.v
@@ -0,0 +1,324 @@ +module adbg_lint_biu +#( + parameter ADDR_WIDTH = 32, + parameter DATA_WIDTH = 64, + parameter AUX_WIDTH = 6 +) +( + tck_i, + trstn_i, + data_i, + data_o, + addr_i, + strobe_i, + rd_wrn_i, + rdy_o, + err_o, + word_size_i, + clk_i, + rstn_i, + lint_req_o, + lint_add_o, + lint_wen_o, + lint_wdata_o, + lint_be_o, + lint_aux_o, + lint_gnt_i, + lint_r_aux_i, + lint_r_valid_i, + lint_r_rdata_i, + lint_r_opc_i +); + //parameter ADDR_WIDTH = 32; + //parameter DATA_WIDTH = 64; + //parameter AUX_WIDTH = 6; + input wire tck_i; + input wire trstn_i; + input wire [63:0] data_i; + output reg [63:0] data_o; + input wire [31:0] addr_i; + input wire strobe_i; + input wire rd_wrn_i; + output reg rdy_o; + output wire err_o; + input wire [3:0] word_size_i; + input wire clk_i; + input wire rstn_i; + output reg lint_req_o; + output wire [ADDR_WIDTH - 1:0] lint_add_o; + output reg lint_wen_o; + output wire [DATA_WIDTH - 1:0] lint_wdata_o; + output wire [(DATA_WIDTH / 8) - 1:0] lint_be_o; + output wire [AUX_WIDTH - 1:0] lint_aux_o; + input wire lint_gnt_i; + input wire lint_r_aux_i; + input wire lint_r_valid_i; + input wire [DATA_WIDTH - 1:0] lint_r_rdata_i; + input wire lint_r_opc_i; + reg [(DATA_WIDTH / 8) - 1:0] sel_reg; + reg [ADDR_WIDTH - 1:0] addr_reg; + reg [DATA_WIDTH - 1:0] data_in_reg; + reg [DATA_WIDTH - 1:0] data_out_reg; + reg wr_reg; + reg str_sync; + reg rdy_sync; + reg err_reg; + reg rdy_sync_tff1; + reg rdy_sync_tff2; + reg rdy_sync_tff2q; + reg str_sync_wbff1; + reg str_sync_wbff2; + reg str_sync_wbff2q; + reg data_o_en; + reg rdy_sync_en; + reg err_en; + reg [(DATA_WIDTH / 8) - 1:0] be_dec; + wire start_toggle; + reg [DATA_WIDTH - 1:0] swapped_data_i; + reg [DATA_WIDTH - 1:0] swapped_data_out; + reg [1:0] lint_fsm_state; + reg [1:0] next_fsm_state; + generate + if (DATA_WIDTH == 64) begin : genblk1 + always @(*) + case (word_size_i) + 4'h1: + if (addr_i[2:0] == 3'b000) + be_dec = 8'b00000001; + else if (addr_i[2:0] == 3'b001) + be_dec = 8'b00000010; + else if (addr_i[2:0] == 3'b010) + be_dec = 8'b00000100; + else if (addr_i[2:0] == 3'b011) + be_dec = 8'b00001000; + else if (addr_i[2:0] == 3'b100) + be_dec = 8'b00010000; + else if (addr_i[2:0] == 3'b101) + be_dec = 8'b00100000; + else if (addr_i[2:0] == 3'b110) + be_dec = 8'b01000000; + else + be_dec = 8'b10000000; + 4'h2: + if (addr_i[2:1] == 2'b00) + be_dec = 8'b00000011; + else if (addr_i[2:1] == 2'b01) + be_dec = 8'b00001100; + else if (addr_i[2:1] == 2'b10) + be_dec = 8'b00110000; + else + be_dec = 8'b11000000; + 4'h4: + if (addr_i[2] == 1'b0) + be_dec = 8'b00001111; + else + be_dec = 8'b11110000; + 4'h8: be_dec = 8'b11111111; + default: be_dec = 8'b11111111; + endcase + end + else if (DATA_WIDTH == 32) begin : genblk1 + always @(*) + case (word_size_i) + 4'h1: + if (addr_i[1:0] == 2'b00) + be_dec = 4'b0001; + else if (addr_i[1:0] == 2'b01) + be_dec = 4'b0010; + else if (addr_i[1:0] == 2'b10) + be_dec = 4'b0100; + else + be_dec = 4'b1000; + 4'h2: + if (addr_i[1] == 1'b0) + be_dec = 4'b0011; + else + be_dec = 4'b1100; + 4'h4: be_dec = 4'b1111; + 4'h8: be_dec = 4'b1111; + default: be_dec = 4'b1111; + endcase + end + if (DATA_WIDTH == 64) begin : genblk2 + always @(*) + case (be_dec) + 8'b00001111: swapped_data_i = {32'h00000000, data_i[63:32]}; + 8'b11110000: swapped_data_i = {data_i[63:32], 32'h00000000}; + 8'b00000011: swapped_data_i = {48'h000000000000, data_i[63:48]}; + 8'b00001100: swapped_data_i = {32'h00000000, data_i[63:48], 16'h0000}; + 8'b00110000: swapped_data_i = {16'h0000, data_i[63:48], 32'h00000000}; + 8'b11000000: swapped_data_i = {data_i[63:48], 48'h000000000000}; + 8'b00000001: swapped_data_i = {56'h00000000000000, data_i[63:56]}; + 8'b00000010: swapped_data_i = {48'h000000000000, data_i[63:56], 8'h00}; + 8'b00000100: swapped_data_i = {40'h0000000000, data_i[63:56], 16'h0000}; + 8'b00001000: swapped_data_i = {32'h00000000, data_i[63:56], 24'h000000}; + 8'b00010000: swapped_data_i = {24'h000000, data_i[63:56], 32'h00000000}; + 8'b00100000: swapped_data_i = {16'h0000, data_i[63:56], 40'h0000000000}; + 8'b01000000: swapped_data_i = {8'h00, data_i[63:56], 48'h000000000000}; + 8'b10000000: swapped_data_i = {data_i[63:56], 56'h00000000000000}; + default: swapped_data_i = data_i; + endcase + end + else if (DATA_WIDTH == 32) begin : genblk2 + always @(*) + case (be_dec) + 4'b1111: swapped_data_i = data_i[63:32]; + 4'b0011: swapped_data_i = {16'h0000, data_i[63:48]}; + 4'b1100: swapped_data_i = {data_i[63:48], 16'h0000}; + 4'b0001: swapped_data_i = {24'h000000, data_i[63:56]}; + 4'b0010: swapped_data_i = {16'h0000, data_i[63:56], 8'h00}; + 4'b0100: swapped_data_i = {8'h00, data_i[63:56], 16'h0000}; + 4'b1000: swapped_data_i = {data_i[63:56], 24'h000000}; + default: swapped_data_i = data_i[63:32]; + endcase + end + if (DATA_WIDTH == 64) begin : genblk3 + always @(*) + case (sel_reg) + 8'b00001111: swapped_data_out = lint_r_rdata_i; + 8'b11110000: swapped_data_out = {32'h00000000, lint_r_rdata_i[63:32]}; + 8'b00000011: swapped_data_out = lint_r_rdata_i; + 8'b00001100: swapped_data_out = {16'h0000, lint_r_rdata_i[63:16]}; + 8'b00110000: swapped_data_out = {32'h00000000, lint_r_rdata_i[63:32]}; + 8'b11000000: swapped_data_out = {48'h000000000000, lint_r_rdata_i[63:48]}; + 8'b00000001: swapped_data_out = lint_r_rdata_i; + 8'b00000010: swapped_data_out = {8'h00, lint_r_rdata_i[63:8]}; + 8'b00000100: swapped_data_out = {16'h0000, lint_r_rdata_i[63:16]}; + 8'b00001000: swapped_data_out = {24'h000000, lint_r_rdata_i[63:24]}; + 8'b00010000: swapped_data_out = {32'h00000000, lint_r_rdata_i[63:32]}; + 8'b00100000: swapped_data_out = {40'h0000000000, lint_r_rdata_i[63:40]}; + 8'b01000000: swapped_data_out = {48'h000000000000, lint_r_rdata_i[63:48]}; + 8'b10000000: swapped_data_out = {56'h00000000000000, lint_r_rdata_i[63:56]}; + default: swapped_data_out = lint_r_rdata_i; + endcase + end + else if (DATA_WIDTH == 32) begin : genblk3 + always @(*) + case (sel_reg) + 4'b1111: swapped_data_out = lint_r_rdata_i; + 4'b0011: swapped_data_out = lint_r_rdata_i; + 4'b1100: swapped_data_out = {16'h0000, lint_r_rdata_i[31:16]}; + 4'b0001: swapped_data_out = lint_r_rdata_i; + 4'b0010: swapped_data_out = {8'h00, lint_r_rdata_i[31:8]}; + 4'b0100: swapped_data_out = {16'h0000, lint_r_rdata_i[31:16]}; + 4'b1000: swapped_data_out = {24'h000000, lint_r_rdata_i[31:24]}; + default: swapped_data_out = lint_r_rdata_i; + endcase + end + endgenerate + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) begin + sel_reg <= 'h0; + addr_reg <= 'h0; + data_in_reg <= 'h0; + wr_reg <= 1'b0; + end + else if (strobe_i && rdy_o) begin + sel_reg <= be_dec; + addr_reg <= addr_i; + if (!rd_wrn_i) + data_in_reg <= swapped_data_i; + wr_reg <= ~rd_wrn_i; + end + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + str_sync <= 1'b0; + else if (strobe_i && rdy_o) + str_sync <= ~str_sync; + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) begin + rdy_sync_tff1 <= 1'b0; + rdy_sync_tff2 <= 1'b0; + rdy_sync_tff2q <= 1'b0; + end + else begin + rdy_sync_tff1 <= rdy_sync; + rdy_sync_tff2 <= rdy_sync_tff1; + rdy_sync_tff2q <= rdy_sync_tff2; + end + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + rdy_o <= 1'b1; + else if (strobe_i && rdy_o) + rdy_o <= 1'b0; + else if (rdy_sync_tff2 != rdy_sync_tff2q) + rdy_o <= 1'b1; + assign lint_add_o = addr_reg; + assign lint_wdata_o = data_in_reg; + assign lint_be_o = sel_reg; + always @(*) + if (DATA_WIDTH == 64) + data_o = data_out_reg; + else if (DATA_WIDTH == 32) + data_o = {32'h00000000, data_out_reg}; + assign err_o = err_reg; + assign lint_aux_o = 'h0; + always @(posedge clk_i or negedge rstn_i) + if (!rstn_i) begin + str_sync_wbff1 <= 1'b0; + str_sync_wbff2 <= 1'b0; + str_sync_wbff2q <= 1'b0; + end + else begin + str_sync_wbff1 <= str_sync; + str_sync_wbff2 <= str_sync_wbff1; + str_sync_wbff2q <= str_sync_wbff2; + end + assign start_toggle = str_sync_wbff2 != str_sync_wbff2q; + always @(posedge clk_i or negedge rstn_i) + if (!rstn_i) + err_reg <= 1'b0; + else if (err_en) + err_reg <= 1'b0; + always @(posedge clk_i or negedge rstn_i) + if (!rstn_i) + data_out_reg <= 32'h00000000; + else if (data_o_en) + data_out_reg <= swapped_data_out; + always @(posedge clk_i or negedge rstn_i) + if (!rstn_i) + rdy_sync <= 1'b0; + else if (rdy_sync_en) + rdy_sync <= ~rdy_sync; + always @(posedge clk_i or negedge rstn_i) + if (~rstn_i) + lint_fsm_state <= 2'd0; + else + lint_fsm_state <= next_fsm_state; + always @(*) begin + lint_wen_o = 1'b1; + lint_req_o = 1'b0; + next_fsm_state = lint_fsm_state; + rdy_sync_en = 1'b0; + data_o_en = 1'b0; + err_en = 1'b0; + case (lint_fsm_state) + 2'd0: + if (start_toggle) + next_fsm_state = 2'd1; + else + next_fsm_state = 2'd0; + 2'd1: begin + lint_req_o = 1'b1; + if (wr_reg) + lint_wen_o = 1'b0; + if (lint_gnt_i) + if (wr_reg) begin + next_fsm_state = 2'd0; + rdy_sync_en = 1'b1; + err_en = 1'b1; + end + else + next_fsm_state = 2'd2; + end + 2'd2: + if (lint_r_valid_i) begin + next_fsm_state = 2'd0; + rdy_sync_en = 1'b1; + err_en = 1'b1; + if (!wr_reg) + data_o_en = 1'b1; + end + endcase + end +endmodule
diff --git a/verilog/rtl/ips/adv_dbg_if/rtl/adbg_lint_defines.v b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_lint_defines.v new file mode 100644 index 0000000..0eb9c4c --- /dev/null +++ b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_lint_defines.v
@@ -0,0 +1,94 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// adbg_wb_defines.v //// +//// //// +//// //// +//// This file is part of the SoC Advanced Debug Interface. //// +//// //// +//// Author(s): //// +//// Nathan Yawn (nathan.yawn@opencores.org) //// +//// //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008-2010 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source 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 Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: adbg_wb_defines.v,v $ +// Revision 1.4 2010-01-10 22:54:11 Nathan +// Update copyright dates +// +// Revision 1.3 2009/05/17 20:54:57 Nathan +// Changed email address to opencores.org +// +// Revision 1.2 2009/05/04 00:50:11 Nathan +// Changed the AXI BIU to use big-endian byte ordering, to match the OR1000. Kept little-endian ordering as a compile-time option in case this is ever used with a little-endian CPU. +// +// Revision 1.1 2008/07/22 20:28:32 Nathan +// Changed names of all files and modules (prefixed an a, for advanced). Cleanup, indenting. No functional changes. +// + +// Endian-ness of the Wishbone interface. +// Default is BIG endian, to match the OR1200. +// If using a LITTLE endian CPU, e.g. an x86, un-comment this line. +//`define DBG_AXI_LITTLE_ENDIAN + +// These relate to the number of internal registers, and how +// many bits are required in the Reg. Select register +`define DBG_LINT_REGSELECT_SIZE 1 +`define DBG_LINT_NUM_INTREG 1 + +// Register index definitions for module-internal registers +// The LINT module has just 1, the error register +`define DBG_LINT_INTREG_ERROR 1'b0 + +// Valid commands/opcodes for the wishbone debug module +// 0000 NOP +// 0001 Write burst, 8-bit access +// 0010 Write burst, 16-bit access +// 0011 Write burst, 32-bit access +// 0100 Write burst, 64-bit access +// 0101 Read burst, 8-bit access +// 0110 Read burst, 16-bit access +// 0111 Read burst, 32-bit access +// 1000 Read burst, 64-bit access +// 1001 Internal register select/write +// 1010 - 1100 Reserved +// 1101 Internal register select +// 1110 - 1111 Reserved + +`define DBG_LINT_CMD_BWRITE8 4'h1 +`define DBG_LINT_CMD_BWRITE16 4'h2 +`define DBG_LINT_CMD_BWRITE32 4'h3 +`define DBG_LINT_CMD_BWRITE64 4'h4 +`define DBG_LINT_CMD_BREAD8 4'h5 +`define DBG_LINT_CMD_BREAD16 4'h6 +`define DBG_LINT_CMD_BREAD32 4'h7 +`define DBG_LINT_CMD_BREAD64 4'h8 +`define DBG_LINT_CMD_IREG_WR 4'h9 +`define DBG_LINT_CMD_IREG_SEL 4'hd
diff --git a/verilog/rtl/ips/adv_dbg_if/rtl/adbg_lint_module.v b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_lint_module.v new file mode 100644 index 0000000..d9b3cdc --- /dev/null +++ b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_lint_module.v
@@ -0,0 +1,528 @@ +module adbg_lint_module +#( + parameter ADDR_WIDTH = 32, + parameter DATA_WIDTH = 64, + parameter AUX_WIDTH = 6 +) +( + tck_i, + module_tdo_o, + tdi_i, + capture_dr_i, + shift_dr_i, + update_dr_i, + data_register_i, + module_select_i, + top_inhibit_o, + trstn_i, + clk_i, + rstn_i, + lint_req_o, + lint_add_o, + lint_wen_o, + lint_wdata_o, + lint_be_o, + lint_aux_o, + lint_gnt_i, + lint_r_aux_i, + lint_r_valid_i, + lint_r_rdata_i, + lint_r_opc_i +); + //parameter ADDR_WIDTH = 32; + //parameter DATA_WIDTH = 64; + //parameter AUX_WIDTH = 6; + input wire tck_i; + output reg module_tdo_o; + input wire tdi_i; + input wire capture_dr_i; + input wire shift_dr_i; + input wire update_dr_i; + input wire [63:0] data_register_i; + input wire module_select_i; + output reg top_inhibit_o; + input wire trstn_i; + input wire clk_i; + input wire rstn_i; + output wire lint_req_o; + output wire [ADDR_WIDTH - 1:0] lint_add_o; + output wire lint_wen_o; + output wire [DATA_WIDTH - 1:0] lint_wdata_o; + output wire [(DATA_WIDTH / 8) - 1:0] lint_be_o; + output wire [AUX_WIDTH - 1:0] lint_aux_o; + input wire lint_gnt_i; + input wire lint_r_aux_i; + input wire lint_r_valid_i; + input wire [DATA_WIDTH - 1:0] lint_r_rdata_i; + input wire lint_r_opc_i; + reg [31:0] address_counter; + reg [5:0] bit_count; + reg [15:0] word_count; + reg [3:0] operation; + reg [64:0] data_out_shift_reg; + reg [0:0] internal_register_select; + reg [32:0] internal_reg_error; + reg addr_sel; + reg addr_ct_en; + reg op_reg_en; + reg bit_ct_en; + reg bit_ct_rst; + reg word_ct_sel; + reg word_ct_en; + reg out_reg_ld_en; + reg out_reg_shift_en; + reg out_reg_data_sel; + reg [1:0] tdo_output_sel; + reg biu_strobe; + reg crc_clr; + reg crc_en; + reg crc_in_sel; + reg crc_shift_en; + reg regsel_ld_en; + reg intreg_ld_en; + reg error_reg_en; + reg biu_clr_err; + wire word_count_zero; + wire bit_count_max; + wire module_cmd; + wire biu_ready; + wire biu_err; + wire burst_read; + wire burst_write; + wire intreg_instruction; + wire intreg_write; + reg rd_op; + wire crc_match; + wire bit_count_32; + reg [5:0] word_size_bits; + reg [3:0] word_size_bytes; + wire [32:0] incremented_address; + wire [31:0] data_to_addr_counter; + wire [15:0] data_to_word_counter; + wire [15:0] decremented_word_count; + wire [31:0] address_data_in; + wire [15:0] count_data_in; + wire [3:0] operation_in; + wire [63:0] data_to_biu; + wire [63:0] data_from_biu; + wire [31:0] crc_data_out; + wire crc_data_in; + wire crc_serial_out; + wire [0:0] reg_select_data; + wire [64:0] out_reg_data; + reg [64:0] data_from_internal_reg; + wire biu_rst; + reg [3:0] module_state; + reg [3:0] module_next_state; + assign module_cmd = ~data_register_i[63]; + assign operation_in = data_register_i[62:59]; + assign address_data_in = data_register_i[58:27]; + assign count_data_in = data_register_i[26:11]; + assign data_to_biu = {tdi_i, data_register_i[63:1]}; + assign reg_select_data = data_register_i[58:57]; + assign intreg_instruction = (operation_in == 4'h9) | (operation_in == 4'hd); + assign intreg_write = operation_in == 4'h9; + assign burst_write = (((operation_in == 4'h1) | (operation_in == 4'h2)) | (operation_in == 4'h3)) | (operation_in == 4'h4); + assign burst_read = (((operation_in == 4'h5) | (operation_in == 4'h6)) | (operation_in == 4'h7)) | (operation_in == 4'h8); + always @(operation) + case (operation) + 4'h1: begin + word_size_bits <= 6'd7; + word_size_bytes <= 4'd1; + rd_op <= 1'b0; + end + 4'h2: begin + word_size_bits <= 6'd15; + word_size_bytes <= 4'd2; + rd_op <= 1'b0; + end + 4'h3: begin + word_size_bits <= 6'd31; + word_size_bytes <= 4'd4; + rd_op <= 1'b0; + end + 4'h4: begin + word_size_bits <= 6'd63; + word_size_bytes <= 4'd8; + rd_op <= 1'b0; + end + 4'h5: begin + word_size_bits <= 6'd7; + word_size_bytes <= 4'd1; + rd_op <= 1'b1; + end + 4'h6: begin + word_size_bits <= 6'd15; + word_size_bytes <= 4'd2; + rd_op <= 1'b1; + end + 4'h7: begin + word_size_bits <= 6'd31; + word_size_bytes <= 4'd4; + rd_op <= 1'b1; + end + 4'h8: begin + word_size_bits <= 6'd63; + word_size_bytes <= 4'd4; + rd_op <= 1'b1; + end + default: begin + word_size_bits <= 6'hxx; + word_size_bytes <= 4'hx; + rd_op <= 1'bx; + end + endcase + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + internal_register_select = 1'h0; + else if (regsel_ld_en) + internal_register_select = reg_select_data; + always @(internal_register_select or internal_reg_error) + case (internal_register_select) + 1'b0: data_from_internal_reg = internal_reg_error; + default: data_from_internal_reg = internal_reg_error; + endcase + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + internal_reg_error = 33'h000000000; + else if (intreg_ld_en && (reg_select_data == 1'b0)) begin + if (data_register_i[46]) + internal_reg_error[0] = 1'b0; + end + else if (error_reg_en && !internal_reg_error[0]) begin + if (biu_err || !biu_ready) + internal_reg_error[0] = 1'b1; + else if (biu_strobe) + internal_reg_error[32:1] = address_counter; + end + else if (biu_strobe && !internal_reg_error[0]) + internal_reg_error[32:1] = address_counter; + assign data_to_addr_counter = (addr_sel ? incremented_address[31:0] : address_data_in); + assign incremented_address = address_counter + word_size_bytes; + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + address_counter <= 32'h00000000; + else if (addr_ct_en) + address_counter <= data_to_addr_counter; + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + operation <= 4'h0; + else if (op_reg_en) + operation <= operation_in; + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + bit_count <= 6'h00; + else if (bit_ct_rst) + bit_count <= 6'h00; + else if (bit_ct_en) + bit_count <= bit_count + 6'h01; + assign bit_count_max = (bit_count == word_size_bits ? 1'b1 : 1'b0); + assign bit_count_32 = (bit_count == 6'h20 ? 1'b1 : 1'b0); + assign data_to_word_counter = (word_ct_sel ? decremented_word_count : count_data_in); + assign decremented_word_count = word_count - 16'h0001; + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + word_count <= 16'h0000; + else if (word_ct_en) + word_count <= data_to_word_counter; + assign word_count_zero = word_count == 16'h0000; + assign out_reg_data = (out_reg_data_sel ? data_from_internal_reg : {1'b0, data_from_biu}); + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + data_out_shift_reg <= 'h0; + else if (out_reg_ld_en) + data_out_shift_reg <= out_reg_data; + else if (out_reg_shift_en) + data_out_shift_reg <= {1'b0, data_out_shift_reg[64:1]}; + always @(tdo_output_sel or data_out_shift_reg[0] or biu_ready or crc_match or crc_serial_out) + if (tdo_output_sel == 2'h0) + module_tdo_o <= biu_ready; + else if (tdo_output_sel == 2'h1) + module_tdo_o <= data_out_shift_reg[0]; + else if (tdo_output_sel == 2'h2) + module_tdo_o <= crc_match; + else + module_tdo_o <= crc_serial_out; + adbg_lint_biu #( + .ADDR_WIDTH(ADDR_WIDTH), + .DATA_WIDTH(DATA_WIDTH), + .AUX_WIDTH(AUX_WIDTH) + ) lint_biu_i( + .tck_i(tck_i), + .trstn_i(trstn_i), + .data_i(data_to_biu), + .data_o(data_from_biu), + .addr_i(address_counter), + .strobe_i(biu_strobe), + .rd_wrn_i(rd_op), + .rdy_o(biu_ready), + .err_o(biu_err), + .word_size_i(word_size_bytes), + .clk_i(clk_i), + .rstn_i(rstn_i), + .lint_req_o(lint_req_o), + .lint_add_o(lint_add_o), + .lint_wen_o(lint_wen_o), + .lint_wdata_o(lint_wdata_o), + .lint_be_o(lint_be_o), + .lint_aux_o(lint_aux_o), + .lint_gnt_i(lint_gnt_i), + .lint_r_aux_i(lint_r_aux_i), + .lint_r_valid_i(lint_r_valid_i), + .lint_r_rdata_i(lint_r_rdata_i), + .lint_r_opc_i(lint_r_opc_i) + ); + assign crc_data_in = (crc_in_sel ? tdi_i : data_out_shift_reg[0]); + adbg_crc32 lint_crc_i( + .clk(tck_i), + .data(crc_data_in), + .enable(crc_en), + .shift(crc_shift_en), + .clr(crc_clr), + .rstn(trstn_i), + .crc_out(crc_data_out), + .serial_out(crc_serial_out) + ); + assign crc_match = (data_register_i[63:32] == crc_data_out ? 1'b1 : 1'b0); + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + module_state <= 4'd0; + else + module_state <= module_next_state; + always @(module_state or module_select_i or module_cmd or update_dr_i or capture_dr_i or operation_in[2] or word_count_zero or bit_count_max or data_register_i[63] or bit_count_32 or biu_ready or burst_read or burst_write) + case (module_state) + 4'd0: + if (((module_cmd && module_select_i) && update_dr_i) && burst_read) + module_next_state <= 4'd1; + else if (((module_cmd && module_select_i) && update_dr_i) && burst_write) + module_next_state <= 4'd5; + else + module_next_state <= 4'd0; + 4'd1: + if (word_count_zero) + module_next_state <= 4'd0; + else + module_next_state <= 4'd2; + 4'd2: + if (module_select_i && capture_dr_i) + module_next_state <= 4'd3; + else + module_next_state <= 4'd2; + 4'd3: + if (update_dr_i) + module_next_state <= 4'd0; + else if (biu_ready) + module_next_state <= 4'd4; + else + module_next_state <= 4'd3; + 4'd4: + if (update_dr_i) + module_next_state <= 4'd0; + else if (bit_count_max && word_count_zero) + module_next_state <= 4'd9; + else + module_next_state <= 4'd4; + 4'd9: + if (update_dr_i) + module_next_state <= 4'd0; + else + module_next_state <= 4'd9; + 4'd5: + if (word_count_zero) + module_next_state <= 4'd0; + else if (module_select_i && capture_dr_i) + module_next_state <= 4'd6; + else + module_next_state <= 4'd5; + 4'd6: + if (update_dr_i) + module_next_state <= 4'd0; + else if (module_select_i && data_register_i[63]) + module_next_state <= 4'd7; + else + module_next_state <= 4'd6; + 4'd7: + if (update_dr_i) + module_next_state <= 4'd0; + else if (bit_count_max) begin + if (word_count_zero) + module_next_state <= 4'd10; + else + module_next_state <= 4'd7; + end + else + module_next_state <= 4'd7; + 4'd8: + if (update_dr_i) + module_next_state <= 4'd0; + else if (word_count_zero) + module_next_state <= 4'd10; + else + module_next_state <= 4'd7; + 4'd10: + if (update_dr_i) + module_next_state <= 4'd0; + else if (bit_count_32) + module_next_state <= 4'd11; + else + module_next_state <= 4'd10; + 4'd11: + if (update_dr_i) + module_next_state <= 4'd0; + else + module_next_state <= 4'd11; + default: module_next_state <= 4'd0; + endcase + always @(module_state or module_next_state or module_select_i or update_dr_i or capture_dr_i or shift_dr_i or operation_in[2] or word_count_zero or bit_count_max or data_register_i[52] or biu_ready or intreg_instruction or module_cmd or intreg_write or decremented_word_count) begin + addr_sel <= 1'b1; + addr_ct_en <= 1'b0; + op_reg_en <= 1'b0; + bit_ct_en <= 1'b0; + bit_ct_rst <= 1'b0; + word_ct_sel <= 1'b1; + word_ct_en <= 1'b0; + out_reg_ld_en <= 1'b0; + out_reg_shift_en <= 1'b0; + tdo_output_sel <= 2'b01; + biu_strobe <= 1'b0; + crc_clr <= 1'b0; + crc_en <= 1'b0; + crc_in_sel <= 1'b0; + crc_shift_en <= 1'b0; + out_reg_data_sel <= 1'b1; + regsel_ld_en <= 1'b0; + intreg_ld_en <= 1'b0; + error_reg_en <= 1'b0; + biu_clr_err <= 1'b0; + top_inhibit_o <= 1'b0; + case (module_state) + 4'd0: begin + addr_sel <= 1'b0; + word_ct_sel <= 1'b0; + if (module_select_i & shift_dr_i) + out_reg_shift_en <= 1'b1; + if (module_select_i & capture_dr_i) begin + out_reg_data_sel <= 1'b1; + out_reg_ld_en <= 1'b1; + end + if ((module_select_i & module_cmd) & update_dr_i) begin + if (intreg_instruction) + regsel_ld_en <= 1'b1; + if (intreg_write) + intreg_ld_en <= 1'b1; + end + if (module_next_state != 4'd0) begin + addr_ct_en <= 1'b1; + op_reg_en <= 1'b1; + bit_ct_rst <= 1'b1; + word_ct_en <= 1'b1; + crc_clr <= 1'b1; + end + end + 4'd1: + if (!word_count_zero) begin + biu_strobe <= 1'b1; + addr_sel <= 1'b1; + addr_ct_en <= 1'b1; + end + 4'd2: + ; + 4'd3: begin + tdo_output_sel <= 2'h0; + top_inhibit_o <= 1'b1; + if (module_next_state == 4'd4) begin + error_reg_en <= 1'b1; + out_reg_data_sel <= 1'b0; + out_reg_ld_en <= 1'b1; + bit_ct_rst <= 1'b1; + word_ct_sel <= 1'b1; + word_ct_en <= 1'b1; + if ((decremented_word_count != 0) && !word_count_zero) begin + biu_strobe <= 1'b1; + addr_sel <= 1'b1; + addr_ct_en <= 1'b1; + end + end + end + 4'd4: begin + tdo_output_sel <= 2'h1; + out_reg_shift_en <= 1'b1; + bit_ct_en <= 1'b1; + crc_en <= 1'b1; + crc_in_sel <= 1'b0; + top_inhibit_o <= 1'b1; + if (bit_count_max) begin + error_reg_en <= 1'b1; + out_reg_data_sel <= 1'b0; + out_reg_ld_en <= 1'b1; + bit_ct_rst <= 1'b1; + word_ct_sel <= 1'b1; + word_ct_en <= 1'b1; + if ((decremented_word_count != 0) && !word_count_zero) begin + biu_strobe <= 1'b1; + addr_sel <= 1'b1; + addr_ct_en <= 1'b1; + end + end + end + 4'd9: begin + tdo_output_sel <= 2'h3; + crc_shift_en <= 1'b1; + top_inhibit_o <= 1'b1; + end + 4'd5: + ; + 4'd6: begin + tdo_output_sel <= 2'h1; + top_inhibit_o <= 1'b1; + if (module_next_state == 4'd7) begin + biu_clr_err <= 1'b1; + bit_ct_en <= 1'b1; + word_ct_sel <= 1'b1; + word_ct_en <= 1'b1; + crc_en <= 1'b1; + crc_in_sel <= 1'b1; + end + end + 4'd7: begin + bit_ct_en <= 1'b1; + tdo_output_sel <= 2'h1; + crc_en <= 1'b1; + crc_in_sel <= 1'b1; + top_inhibit_o <= 1'b1; + if (bit_count_max) begin + error_reg_en <= 1'b1; + bit_ct_rst <= 1'b1; + biu_strobe <= 1'b1; + addr_ct_en <= 1'b1; + word_ct_sel <= 1'b1; + word_ct_en <= 1'b1; + end + end + 4'd8: begin + tdo_output_sel <= 2'h0; + error_reg_en <= 1'b1; + biu_strobe <= 1'b1; + word_ct_sel <= 1'b1; + word_ct_en <= 1'b1; + bit_ct_rst <= 1'b1; + addr_ct_en <= 1'b1; + top_inhibit_o <= 1'b1; + end + 4'd10: begin + bit_ct_en <= 1'b1; + top_inhibit_o <= 1'b1; + if (module_next_state == 4'd11) + tdo_output_sel <= 2'h2; + end + 4'd11: begin + tdo_output_sel <= 2'h2; + top_inhibit_o <= 1'b1; + if (module_next_state == 4'd0) + error_reg_en <= 1'b1; + end + default: + ; + endcase + end +endmodule
diff --git a/verilog/rtl/ips/adv_dbg_if/rtl/adbg_lintonly_top.v b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_lintonly_top.v new file mode 100644 index 0000000..13fb29c --- /dev/null +++ b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_lintonly_top.v
@@ -0,0 +1,120 @@ +module adbg_lintonly_top +#( + parameter ADDR_WIDTH = 32, + parameter DATA_WIDTH = 64, + parameter AUX_WIDTH = 6 +) +( + tck_i, + tdi_i, + tdo_o, + trstn_i, + shift_dr_i, + pause_dr_i, + update_dr_i, + capture_dr_i, + debug_select_i, + clk_i, + rstn_i, + lint_req_o, + lint_add_o, + lint_wen_o, + lint_wdata_o, + lint_be_o, + lint_aux_o, + lint_gnt_i, + lint_r_aux_i, + lint_r_valid_i, + lint_r_rdata_i, + lint_r_opc_i +); + //parameter ADDR_WIDTH = 32; + //parameter DATA_WIDTH = 64; + //parameter AUX_WIDTH = 6; + input wire tck_i; + input wire tdi_i; + output reg tdo_o; + input wire trstn_i; + input wire shift_dr_i; + input wire pause_dr_i; + input wire update_dr_i; + input wire capture_dr_i; + input wire debug_select_i; + input wire clk_i; + input wire rstn_i; + output wire lint_req_o; + output wire [ADDR_WIDTH - 1:0] lint_add_o; + output wire lint_wen_o; + output wire [DATA_WIDTH - 1:0] lint_wdata_o; + output wire [(DATA_WIDTH / 8) - 1:0] lint_be_o; + output wire [AUX_WIDTH - 1:0] lint_aux_o; + input wire lint_gnt_i; + input wire lint_r_aux_i; + input wire lint_r_valid_i; + input wire [DATA_WIDTH - 1:0] lint_r_rdata_i; + input wire lint_r_opc_i; + wire tdo_axi; + wire tdo_cpu; + reg [63:0] input_shift_reg; + reg [4:0] module_id_reg; + wire select_cmd; + wire [4:0] module_id_in; + reg [1:0] module_selects; + wire select_inhibit; + wire [1:0] module_inhibit; + integer j; + assign select_cmd = input_shift_reg[63]; + assign module_id_in = input_shift_reg[62:58]; + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + module_id_reg <= 5'h00; + else if (((debug_select_i && select_cmd) && update_dr_i) && !select_inhibit) + module_id_reg <= module_id_in; + always @(*) + if (module_id_reg == 0) + module_selects = 2'b01; + else + module_selects = 2'b10; + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + input_shift_reg <= 'h0; + else if (debug_select_i && shift_dr_i) + input_shift_reg <= {tdi_i, input_shift_reg[63:1]}; + adbg_lint_module #( + .ADDR_WIDTH(ADDR_WIDTH), + .DATA_WIDTH(DATA_WIDTH), + .AUX_WIDTH(AUX_WIDTH) + ) i_dbg_lint( + .tck_i(tck_i), + .module_tdo_o(tdo_axi), + .tdi_i(tdi_i), + .capture_dr_i(capture_dr_i), + .shift_dr_i(shift_dr_i), + .update_dr_i(update_dr_i), + .data_register_i(input_shift_reg), + .module_select_i(module_selects[0]), + .top_inhibit_o(module_inhibit[0]), + .trstn_i(trstn_i), + .clk_i(clk_i), + .rstn_i(rstn_i), + .lint_req_o(lint_req_o), + .lint_add_o(lint_add_o), + .lint_wen_o(lint_wen_o), + .lint_wdata_o(lint_wdata_o), + .lint_be_o(lint_be_o), + .lint_aux_o(lint_aux_o), + .lint_gnt_i(lint_gnt_i), + .lint_r_aux_i(lint_r_aux_i), + .lint_r_valid_i(lint_r_valid_i), + .lint_r_rdata_i(lint_r_rdata_i), + .lint_r_opc_i(lint_r_opc_i) + ); + assign select_inhibit = |module_inhibit; + always @(module_id_reg or tdo_axi or tdo_cpu) + if (module_id_reg == 0) + tdo_o <= tdo_axi; + else if (module_id_reg == 1) + tdo_o <= tdo_cpu; + else + tdo_o <= 1'b0; +endmodule
diff --git a/verilog/rtl/ips/adv_dbg_if/rtl/adbg_or1k_biu.v b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_or1k_biu.v new file mode 100644 index 0000000..3547656 --- /dev/null +++ b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_or1k_biu.v
@@ -0,0 +1,188 @@ +module adbg_or1k_biu +#( + parameter NB_CORES = 4 + ) +( + tck_i, + trstn_i, + cpu_select_i, + data_i, + data_o, + addr_i, + strobe_i, + rd_wrn_i, + rdy_o, + cpu_clk_i, + cpu_rstn_i, + cpu_addr_o, + cpu_data_i, + cpu_data_o, + cpu_stb_o, + cpu_we_o, + cpu_ack_i +); + //parameter NB_CORES = 4; + input wire tck_i; + input wire trstn_i; + input wire [3:0] cpu_select_i; + input wire [31:0] data_i; + output wire [31:0] data_o; + input wire [31:0] addr_i; + input wire strobe_i; + input wire rd_wrn_i; + output reg rdy_o; + input wire cpu_clk_i; + input wire cpu_rstn_i; + output reg [(NB_CORES * 16) - 1:0] cpu_addr_o; + input wire [(NB_CORES * 32) - 1:0] cpu_data_i; + output reg [(NB_CORES * 32) - 1:0] cpu_data_o; + output reg [NB_CORES - 1:0] cpu_stb_o; + output reg [NB_CORES - 1:0] cpu_we_o; + input wire [NB_CORES - 1:0] cpu_ack_i; + reg [31:0] cpu_data_int; + reg cpu_ack_int; + reg cpu_stb_int; + reg [31:0] addr_reg; + reg [31:0] data_in_reg; + reg [31:0] data_out_reg; + reg wr_reg; + reg str_sync; + reg rdy_sync; + reg rdy_sync_tff1; + reg rdy_sync_tff2; + reg rdy_sync_tff2q; + reg str_sync_wbff1; + reg str_sync_wbff2; + reg str_sync_wbff2q; + reg data_o_en; + reg rdy_sync_en; + wire start_toggle; + wire valid_selection; + assign valid_selection = (cpu_select_i < NB_CORES ? 1'b1 : 1'b0); + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) begin + addr_reg <= 32'h00000000; + data_in_reg <= 32'h00000000; + wr_reg <= 1'b0; + end + else if (strobe_i && rdy_o) begin + addr_reg <= addr_i; + if (!rd_wrn_i) + data_in_reg <= data_i; + wr_reg <= ~rd_wrn_i; + end + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + str_sync <= 1'b0; + else if (strobe_i && rdy_o) + str_sync <= ~str_sync; + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) begin + rdy_sync_tff1 <= 1'b0; + rdy_sync_tff2 <= 1'b0; + rdy_sync_tff2q <= 1'b0; + rdy_o <= 1'b1; + end + else begin + rdy_sync_tff1 <= rdy_sync; + rdy_sync_tff2 <= rdy_sync_tff1; + rdy_sync_tff2q <= rdy_sync_tff2; + if (strobe_i && rdy_o) + rdy_o <= 1'b0; + else if (rdy_sync_tff2 != rdy_sync_tff2q) + rdy_o <= 1'b1; + end + assign data_o = data_out_reg; + always @(*) begin : sv2v_autoblock_1 + reg signed [31:0] i; + for (i = 0; i < NB_CORES; i = i + 1) + if (cpu_select_i == i) begin + cpu_data_o[i * 32+:32] = data_in_reg; + cpu_we_o[i] = wr_reg; + cpu_addr_o[i * 16+:16] = addr_reg; + cpu_stb_o[i] = cpu_stb_int; + end + else begin + cpu_data_o[i * 32+:32] = 'h0; + cpu_we_o[i] = 1'b0; + cpu_addr_o[i * 16+:16] = 'h0; + cpu_stb_o[i] = 1'b0; + end + end + always @(*) begin + cpu_data_int = 'h0; + cpu_ack_int = 1'b0; + begin : sv2v_autoblock_2 + reg signed [31:0] i; + for (i = 0; i < NB_CORES; i = i + 1) + if (cpu_select_i == i) begin + cpu_data_int = cpu_data_i[i * 32+:32]; + cpu_ack_int = cpu_ack_i[i]; + end + end + end + always @(posedge cpu_clk_i or negedge cpu_rstn_i) + if (~cpu_rstn_i) begin + str_sync_wbff1 <= 1'b0; + str_sync_wbff2 <= 1'b0; + str_sync_wbff2q <= 1'b0; + end + else begin + str_sync_wbff1 <= str_sync; + str_sync_wbff2 <= str_sync_wbff1; + str_sync_wbff2q <= str_sync_wbff2; + end + assign start_toggle = str_sync_wbff2 != str_sync_wbff2q; + always @(posedge cpu_clk_i or negedge cpu_rstn_i) + if (~cpu_rstn_i) + data_out_reg <= 32'h00000000; + else if (data_o_en) + data_out_reg <= cpu_data_int; + always @(posedge cpu_clk_i or negedge cpu_rstn_i) + if (~cpu_rstn_i) + rdy_sync <= 1'b0; + else if (rdy_sync_en) + rdy_sync <= ~rdy_sync; + reg cpu_fsm_state; + reg next_fsm_state; + always @(posedge cpu_clk_i or negedge cpu_rstn_i) + if (~cpu_rstn_i) + cpu_fsm_state <= 1'h0; + else + cpu_fsm_state <= next_fsm_state; + always @(cpu_fsm_state or start_toggle or cpu_ack_int) + case (cpu_fsm_state) + 1'h0: + if (start_toggle && !cpu_ack_int) + next_fsm_state <= 1'h1; + else + next_fsm_state <= 1'h0; + 1'h1: + if (cpu_ack_int) + next_fsm_state <= 1'h0; + else + next_fsm_state <= 1'h1; + endcase + always @(cpu_fsm_state or start_toggle or cpu_ack_int or wr_reg) begin + rdy_sync_en = 1'b0; + data_o_en = 1'b0; + cpu_stb_int = 1'b0; + case (cpu_fsm_state) + 1'h0: + if (start_toggle) begin + cpu_stb_int = 1'b1; + if (cpu_ack_int) + rdy_sync_en = 1'b1; + if (cpu_ack_int && !wr_reg) + data_o_en = 1'b1; + end + 1'h1: begin + cpu_stb_int = 1'b1; + if (cpu_ack_int) begin + data_o_en = 1'b1; + rdy_sync_en = 1'b1; + end + end + endcase + end +endmodule
diff --git a/verilog/rtl/ips/adv_dbg_if/rtl/adbg_or1k_defines.v b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_or1k_defines.v new file mode 100644 index 0000000..d38fd08 --- /dev/null +++ b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_or1k_defines.v
@@ -0,0 +1,83 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// adbg_or1k_defines.v //// +//// //// +//// //// +//// This file is part of the SoC Advanced Debug Interface. //// +//// //// +//// Author(s): //// +//// Nathan Yawn (nathan.yawn@opencores.org) //// +//// //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2008 - 2010 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source 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 Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: adbg_or1k_defines.v,v $ +// Revision 1.3 2010-01-10 22:54:10 Nathan +// Update copyright dates +// +// Revision 1.2 2009/05/17 20:54:56 Nathan +// Changed email address to opencores.org +// +// Revision 1.1 2008/07/22 20:28:31 Nathan +// Changed names of all files and modules (prefixed an a, for advanced). Cleanup, indenting. No functional changes. +// +// Revision 1.3 2008/07/06 20:02:54 Nathan +// Fixes for synthesis with Xilinx ISE (also synthesizable with +// Quartus II 7.0). Ran through dos2unix. +// +// Revision 1.2 2008/06/26 20:52:31 Nathan +// OR1K module tested and working. Added copyright / license info +// to _define files. Other cleanup. +// + + + +// Register index definitions for module-internal registers +// Index 0 is the Status register, used for stall and reset +`define DBG_OR1K_INTREG_STATUS 3'b000 + +// Valid commands/opcodes for the or1k debug module +// 0000 NOP +// 0001 - 0010 Reserved +// 0011 Write burst, 32-bit access +// 0100 - 0110 Reserved +// 0111 Read burst, 32-bit access +// 1000 Reserved +// 1001 Internal register select/write +// 1010 - 1100 Reserved +// 1101 Internal register select +// 1110 - 1111 Reserved + + +`define DBG_OR1K_CMD_BWRITE32 4'h3 +`define DBG_OR1K_CMD_BREAD32 4'h7 +`define DBG_OR1K_CMD_IREG_WR 4'h9 +`define DBG_OR1K_CMD_IREG_SEL 4'hd
diff --git a/verilog/rtl/ips/adv_dbg_if/rtl/adbg_or1k_module.v b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_or1k_module.v new file mode 100644 index 0000000..4e6a5dd --- /dev/null +++ b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_or1k_module.v
@@ -0,0 +1,460 @@ +module adbg_or1k_module +#( + parameter NB_CORES = 4 + ) + ( + tck_i, + module_tdo_o, + tdi_i, + capture_dr_i, + shift_dr_i, + update_dr_i, + data_register_i, + module_select_i, + top_inhibit_o, + trstn_i, + cpu_clk_i, + cpu_rstn_i, + cpu_addr_o, + cpu_data_i, + cpu_data_o, + cpu_bp_i, + cpu_stall_o, + cpu_stb_o, + cpu_we_o, + cpu_ack_i +); + //parameter NB_CORES = 4; + input wire tck_i; + output reg module_tdo_o; + input wire tdi_i; + input wire capture_dr_i; + input wire shift_dr_i; + input wire update_dr_i; + input wire [56:0] data_register_i; + input wire module_select_i; + output reg top_inhibit_o; + input wire trstn_i; + input cpu_clk_i; + input cpu_rstn_i; + output wire [(NB_CORES * 16) - 1:0] cpu_addr_o; + input wire [(NB_CORES * 32) - 1:0] cpu_data_i; + output wire [(NB_CORES * 32) - 1:0] cpu_data_o; + input wire [NB_CORES - 1:0] cpu_bp_i; + output wire [NB_CORES - 1:0] cpu_stall_o; + output wire [NB_CORES - 1:0] cpu_stb_o; + output wire [NB_CORES - 1:0] cpu_we_o; + input wire [NB_CORES - 1:0] cpu_ack_i; + reg [31:0] address_counter; + reg [5:0] bit_count; + reg [15:0] word_count; + reg [3:0] operation; + reg [31:0] data_out_shift_reg; + reg [2:0] internal_register_select; + wire [NB_CORES - 1:0] internal_reg_status; + reg addr_sel; + reg addr_ct_en; + reg op_reg_en; + reg bit_ct_en; + reg bit_ct_rst; + reg word_ct_sel; + reg word_ct_en; + reg out_reg_ld_en; + reg out_reg_shift_en; + reg out_reg_data_sel; + reg [1:0] tdo_output_sel; + reg biu_strobe; + reg crc_clr; + reg crc_en; + reg crc_in_sel; + reg crc_shift_en; + reg regsel_ld_en; + reg intreg_ld_en; + reg cpusel_ld_en; + wire word_count_zero; + wire bit_count_max; + wire module_cmd; + wire biu_ready; + wire burst_instruction; + wire intreg_instruction; + wire intreg_write; + wire rd_op; + wire crc_match; + wire bit_count_32; + wire [5:0] word_size_bits; + wire [2:0] address_increment; + wire [32:0] incremented_address; + wire [31:0] data_to_addr_counter; + wire [15:0] data_to_word_counter; + wire [15:0] decremented_word_count; + wire [31:0] address_data_in; + wire [15:0] count_data_in; + wire [3:0] operation_in; + wire [31:0] data_to_biu; + wire [31:0] data_from_biu; + wire [31:0] crc_data_out; + wire crc_data_in; + wire crc_serial_out; + wire [2:0] reg_select_data; + wire [31:0] out_reg_data; + reg [31:0] data_from_internal_reg; + wire status_reg_wr; + reg [3:0] cpu_select; + wire [3:0] cpu_select_in; + wire [15:0] status_reg_data; + reg [3:0] module_state; + reg [3:0] module_next_state; + assign module_cmd = ~data_register_i[56]; + assign operation_in = data_register_i[55:52]; + assign cpu_select_in = data_register_i[51:48]; + assign address_data_in = data_register_i[47:16]; + assign count_data_in = data_register_i[15:0]; + assign data_to_biu = {tdi_i, data_register_i[56:26]}; + assign reg_select_data = data_register_i[51:49]; + assign status_reg_data = data_register_i[48:33]; + assign burst_instruction = (operation_in == 4'h3) | (operation_in == 4'h7); + assign intreg_instruction = (operation_in == 4'h9) | (operation_in == 4'hd); + assign intreg_write = operation_in == 4'h9; + assign word_size_bits = 5'd31; + assign address_increment = 3'd1; + assign rd_op = operation[2]; + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + internal_register_select = 'h0; + else if (regsel_ld_en) + internal_register_select = reg_select_data; + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + cpu_select = 'h0; + else if (cpusel_ld_en) + cpu_select = cpu_select_in; + always @(internal_register_select or internal_reg_status) + case (internal_register_select) + 3'b000: data_from_internal_reg = {{32 - NB_CORES {1'b0}}, internal_reg_status}; + default: data_from_internal_reg = {{32 - NB_CORES {1'b0}}, internal_reg_status}; + endcase + assign status_reg_wr = intreg_ld_en & (reg_select_data == 3'b000); + adbg_or1k_status_reg #(.NB_CORES(NB_CORES)) or1k_statusreg_i( + .data_i(status_reg_data), + .we_i(status_reg_wr), + .tck_i(tck_i), + .bp_i(cpu_bp_i), + .trstn_i(trstn_i), + .cpu_clk_i(cpu_clk_i), + .cpu_rstn_i(cpu_rstn_i), + .ctrl_reg_o(internal_reg_status), + .cpu_stall_o(cpu_stall_o) + ); + assign data_to_addr_counter = (addr_sel ? incremented_address[31:0] : address_data_in); + assign incremented_address = address_counter + address_increment; + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + address_counter <= 32'h00000000; + else if (addr_ct_en) + address_counter <= data_to_addr_counter; + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + operation <= 4'h0; + else if (op_reg_en) + operation <= operation_in; + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + bit_count <= 6'h00; + else if (bit_ct_rst) + bit_count <= 6'h00; + else if (bit_ct_en) + bit_count <= bit_count + 6'h01; + assign bit_count_max = (bit_count == word_size_bits ? 1'b1 : 1'b0); + assign bit_count_32 = (bit_count == 6'h20 ? 1'b1 : 1'b0); + assign data_to_word_counter = (word_ct_sel ? decremented_word_count : count_data_in); + assign decremented_word_count = word_count - 16'h0001; + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + word_count <= 16'h0000; + else if (word_ct_en) + word_count <= data_to_word_counter; + assign word_count_zero = word_count == 16'h0000; + assign out_reg_data = (out_reg_data_sel ? data_from_internal_reg : data_from_biu); + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + data_out_shift_reg <= 32'h00000000; + else if (out_reg_ld_en) + data_out_shift_reg <= out_reg_data; + else if (out_reg_shift_en) + data_out_shift_reg <= {1'b0, data_out_shift_reg[31:1]}; + always @(tdo_output_sel or data_out_shift_reg[0] or biu_ready or crc_match or crc_serial_out) + if (tdo_output_sel == 2'h0) + module_tdo_o <= biu_ready; + else if (tdo_output_sel == 2'h1) + module_tdo_o <= data_out_shift_reg[0]; + else if (tdo_output_sel == 2'h2) + module_tdo_o <= crc_match; + else + module_tdo_o <= crc_serial_out; + adbg_or1k_biu #(.NB_CORES(NB_CORES)) or1k_biu_i( + .tck_i(tck_i), + .trstn_i(trstn_i), + .cpu_select_i(cpu_select), + .data_i(data_to_biu), + .data_o(data_from_biu), + .addr_i(address_counter), + .strobe_i(biu_strobe), + .rd_wrn_i(rd_op), + .rdy_o(biu_ready), + .cpu_clk_i(cpu_clk_i), + .cpu_rstn_i(cpu_rstn_i), + .cpu_addr_o(cpu_addr_o), + .cpu_data_i(cpu_data_i), + .cpu_data_o(cpu_data_o), + .cpu_stb_o(cpu_stb_o), + .cpu_we_o(cpu_we_o), + .cpu_ack_i(cpu_ack_i) + ); + assign crc_data_in = (crc_in_sel ? tdi_i : data_out_shift_reg[0]); + adbg_crc32 or1k_crc_i( + .clk(tck_i), + .data(crc_data_in), + .enable(crc_en), + .shift(crc_shift_en), + .clr(crc_clr), + .rstn(trstn_i), + .crc_out(crc_data_out), + .serial_out(crc_serial_out) + ); + assign crc_match = (data_register_i[56:25] == crc_data_out ? 1'b1 : 1'b0); + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + module_state <= 4'd0; + else + module_state <= module_next_state; + always @(module_state or module_select_i or update_dr_i or capture_dr_i or shift_dr_i or operation_in[2] or word_count_zero or bit_count_max or data_register_i[56] or bit_count_32 or biu_ready or module_cmd or intreg_write or decremented_word_count or burst_instruction) + case (module_state) + 4'd0: + if ((((module_cmd && module_select_i) && update_dr_i) && burst_instruction) && operation_in[2]) + module_next_state <= 4'd1; + else if (((module_cmd && module_select_i) && update_dr_i) && burst_instruction) + module_next_state <= 4'd5; + else + module_next_state <= 4'd0; + 4'd1: + if (word_count_zero) + module_next_state <= 4'd0; + else + module_next_state <= 4'd2; + 4'd2: + if (module_select_i && capture_dr_i) + module_next_state <= 4'd3; + else + module_next_state <= 4'd2; + 4'd3: + if (update_dr_i) + module_next_state <= 4'd0; + else if (biu_ready) + module_next_state <= 4'd4; + else + module_next_state <= 4'd3; + 4'd4: + if (update_dr_i) + module_next_state <= 4'd0; + else if (bit_count_max && word_count_zero) + module_next_state <= 4'd9; + else + module_next_state <= 4'd4; + 4'd9: + if (update_dr_i) + module_next_state <= 4'd0; + else + module_next_state <= 4'd9; + 4'd5: + if (word_count_zero) + module_next_state <= 4'd0; + else if (module_select_i && capture_dr_i) + module_next_state <= 4'd6; + else + module_next_state <= 4'd5; + 4'd6: + if (update_dr_i) + module_next_state <= 4'd0; + else if (module_select_i && data_register_i[56]) + module_next_state <= 4'd7; + else + module_next_state <= 4'd6; + 4'd7: + if (update_dr_i) + module_next_state <= 4'd0; + else if (bit_count_max) begin + if (word_count_zero) + module_next_state <= 4'd10; + else + module_next_state <= 4'd7; + end + else + module_next_state <= 4'd7; + 4'd8: + if (update_dr_i) + module_next_state <= 4'd0; + else if (word_count_zero) + module_next_state <= 4'd10; + else + module_next_state <= 4'd7; + 4'd10: + if (update_dr_i) + module_next_state <= 4'd0; + else if (bit_count_32) + module_next_state <= 4'd11; + else + module_next_state <= 4'd10; + 4'd11: + if (update_dr_i) + module_next_state <= 4'd0; + else + module_next_state <= 4'd11; + default: module_next_state <= 4'd0; + endcase + always @(module_state or module_next_state or module_select_i or update_dr_i or capture_dr_i or shift_dr_i or operation_in[2] or word_count_zero or bit_count_max or data_register_i[52] or biu_ready or intreg_instruction or burst_instruction or module_cmd or intreg_write or decremented_word_count) begin + addr_sel <= 1'b1; + addr_ct_en <= 1'b0; + op_reg_en <= 1'b0; + bit_ct_en <= 1'b0; + bit_ct_rst <= 1'b0; + word_ct_sel <= 1'b1; + word_ct_en <= 1'b0; + out_reg_ld_en <= 1'b0; + out_reg_shift_en <= 1'b0; + tdo_output_sel <= 2'b01; + biu_strobe <= 1'b0; + crc_clr <= 1'b0; + crc_en <= 1'b0; + crc_in_sel <= 1'b0; + crc_shift_en <= 1'b0; + out_reg_data_sel <= 1'b1; + regsel_ld_en <= 1'b0; + cpusel_ld_en <= 1'b0; + intreg_ld_en <= 1'b0; + top_inhibit_o <= 1'b0; + case (module_state) + 4'd0: begin + addr_sel <= 1'b0; + word_ct_sel <= 1'b0; + if (module_select_i & shift_dr_i) + out_reg_shift_en <= 1'b1; + if (module_select_i & capture_dr_i) begin + out_reg_data_sel <= 1'b1; + out_reg_ld_en <= 1'b1; + end + if ((module_select_i & module_cmd) & update_dr_i) begin + if (intreg_instruction) + regsel_ld_en <= 1'b1; + if (intreg_write) + intreg_ld_en <= 1'b1; + if (burst_instruction) + cpusel_ld_en <= 1'b1; + end + if (module_next_state != 4'd0) begin + addr_ct_en <= 1'b1; + op_reg_en <= 1'b1; + bit_ct_rst <= 1'b1; + word_ct_en <= 1'b1; + crc_clr <= 1'b1; + end + end + 4'd1: + if (!word_count_zero) begin + biu_strobe <= 1'b1; + addr_sel <= 1'b1; + addr_ct_en <= 1'b1; + end + 4'd2: + ; + 4'd3: begin + tdo_output_sel <= 2'h0; + top_inhibit_o <= 1'b1; + if (module_next_state == 4'd4) begin + out_reg_data_sel <= 1'b0; + out_reg_ld_en <= 1'b1; + bit_ct_rst <= 1'b1; + word_ct_sel <= 1'b1; + word_ct_en <= 1'b1; + if ((decremented_word_count != 0) && !word_count_zero) begin + biu_strobe <= 1'b1; + addr_sel <= 1'b1; + addr_ct_en <= 1'b1; + end + end + end + 4'd4: begin + tdo_output_sel <= 2'h1; + out_reg_shift_en <= 1'b1; + bit_ct_en <= 1'b1; + crc_en <= 1'b1; + crc_in_sel <= 1'b0; + top_inhibit_o <= 1'b1; + if (bit_count_max) begin + out_reg_data_sel <= 1'b0; + out_reg_ld_en <= 1'b1; + bit_ct_rst <= 1'b1; + word_ct_sel <= 1'b1; + word_ct_en <= 1'b1; + if ((decremented_word_count != 0) && !word_count_zero) begin + biu_strobe <= 1'b1; + addr_sel <= 1'b1; + addr_ct_en <= 1'b1; + end + end + end + 4'd9: begin + tdo_output_sel <= 2'h3; + crc_shift_en <= 1'b1; + top_inhibit_o <= 1'b1; + end + 4'd5: + ; + 4'd6: begin + tdo_output_sel <= 2'h1; + top_inhibit_o <= 1'b1; + if (module_next_state == 4'd7) begin + bit_ct_en <= 1'b1; + word_ct_sel <= 1'b1; + word_ct_en <= 1'b1; + crc_en <= 1'b1; + crc_in_sel <= 1'b1; + end + end + 4'd7: begin + bit_ct_en <= 1'b1; + tdo_output_sel <= 2'h1; + crc_en <= 1'b1; + crc_in_sel <= 1'b1; + top_inhibit_o <= 1'b1; + if (bit_count_max) begin + bit_ct_rst <= 1'b1; + biu_strobe <= 1'b1; + addr_ct_en <= 1'b1; + word_ct_sel <= 1'b1; + word_ct_en <= 1'b1; + end + end + 4'd8: begin + tdo_output_sel <= 2'h0; + biu_strobe <= 1'b1; + word_ct_sel <= 1'b1; + word_ct_en <= 1'b1; + bit_ct_rst <= 1'b1; + addr_ct_en <= 1'b1; + top_inhibit_o <= 1'b1; + end + 4'd10: begin + bit_ct_en <= 1'b1; + top_inhibit_o <= 1'b1; + if (module_next_state == 4'd11) + tdo_output_sel <= 2'h2; + end + 4'd11: begin + tdo_output_sel <= 2'h2; + top_inhibit_o <= 1'b1; + end + default: + ; + endcase + end +endmodule
diff --git a/verilog/rtl/ips/adv_dbg_if/rtl/adbg_or1k_status_reg.v b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_or1k_status_reg.v new file mode 100644 index 0000000..3d17036 --- /dev/null +++ b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_or1k_status_reg.v
@@ -0,0 +1,74 @@ +module adbg_or1k_status_reg +#( + parameter NB_CORES = 4 + ) +( + tck_i, + trstn_i, + we_i, + cpu_clk_i, + cpu_rstn_i, + data_i, + bp_i, + ctrl_reg_o, + cpu_stall_o +); + //parameter NB_CORES = 4; + input tck_i; + input trstn_i; + input we_i; + input cpu_clk_i; + input cpu_rstn_i; + input wire [15:0] data_i; + input wire [NB_CORES - 1:0] bp_i; + output wire [NB_CORES - 1:0] ctrl_reg_o; + output wire [NB_CORES - 1:0] cpu_stall_o; + reg [NB_CORES - 1:0] stall_bp; + reg [NB_CORES - 1:0] stall_bp_csff; + reg [NB_CORES - 1:0] stall_bp_tck; + reg [NB_CORES - 1:0] stall_reg; + reg [NB_CORES - 1:0] stall_reg_csff; + reg [NB_CORES - 1:0] stall_reg_cpu; + always @(posedge cpu_clk_i or negedge cpu_rstn_i) + if (~cpu_rstn_i) + stall_bp <= 1'sb0; + else begin : sv2v_autoblock_1 + reg signed [31:0] i; + for (i = 0; i < NB_CORES; i = i + 1) + if (bp_i[i]) + stall_bp[i] <= 1'b1; + else if (stall_reg_cpu[i]) + stall_bp[i] <= 1'b0; + end + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) begin + stall_bp_csff <= 1'sb0; + stall_bp_tck <= 1'sb0; + end + else begin + stall_bp_csff <= stall_bp; + stall_bp_tck <= stall_bp_csff; + end + always @(posedge cpu_clk_i or negedge cpu_rstn_i) + if (~cpu_rstn_i) begin + stall_reg_csff <= 1'sb0; + stall_reg_cpu <= 1'sb0; + end + else begin + stall_reg_csff <= stall_reg; + stall_reg_cpu <= stall_reg_csff; + end + assign cpu_stall_o = (bp_i | stall_bp) | stall_reg_cpu; + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + stall_reg <= 1'sb0; + else begin : sv2v_autoblock_2 + reg signed [31:0] i; + for (i = 0; i < NB_CORES; i = i + 1) + if (stall_bp_tck[i]) + stall_reg[i] <= 1'b1; + else if (we_i) + stall_reg[i] <= data_i[i]; + end + assign ctrl_reg_o = {stall_reg}; +endmodule
diff --git a/verilog/rtl/ips/adv_dbg_if/rtl/adbg_tap_defines.v b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_tap_defines.v new file mode 100644 index 0000000..95c346f --- /dev/null +++ b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_tap_defines.v
@@ -0,0 +1,79 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// tap_defines.v //// +//// //// +//// //// +//// This file is part of the JTAG Test Access Port (TAP) //// +//// http://www.opencores.org/projects/jtag/ //// +//// //// +//// Author(s): //// +//// Igor Mohor (igorm@opencores.org) //// +//// //// +//// //// +//// All additional information is avaliable in the README.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 - 2003 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source 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 Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: tap_defines.v,v $ +// Revision 1.1.1.1 2008-05-14 12:07:33 Nathan +// Original from OpenCores +// +// Revision 1.3 2004/03/02 17:39:45 mohor +// IDCODE_VALUE changed to Flextronics ID. +// +// Revision 1.2 2004/01/27 10:00:33 mohor +// Unused registers removed. +// +// Revision 1.1 2003/12/23 14:52:14 mohor +// Directory structure changed. New version of TAP. +// +// +// + + +// Define IDCODE Value +`define IDCODE_VALUE 32'h249511c3 +// 0001 version +// 0100100101010001 part number (IQ) +// 00011100001 manufacturer id (flextronics) +// 1 required by standard + +// Length of the Instruction register +`define IR_LENGTH 4 + +// Supported Instructions +`define EXTEST 4'b0000 +`define SAMPLE_PRELOAD 4'b0001 +`define IDCODE 4'b0010 +`define DEBUG 4'b1000 +`define MBIST 4'b1001 +`define BYPASS 4'b1111 +
diff --git a/verilog/rtl/ips/adv_dbg_if/rtl/adbg_tap_top.v b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_tap_top.v new file mode 100644 index 0000000..972a77c --- /dev/null +++ b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_tap_top.v
@@ -0,0 +1,551 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// tap_top.v //// +//// //// +//// //// +//// This file is part of the JTAG Test Access Port (TAP) //// +//// //// +//// Author(s): //// +//// Igor Mohor (igorm@opencores.org) //// +//// Nathan Yawn (nathan.yawn@opencores.org) //// +//// //// +//// //// +//// All additional information is avaliable in the jtag.pdf //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 - 2008 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source 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 Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: tap_top.v,v $ +// Revision 1.6 2011-10-24 02:18:58 natey +// Removed '#1' delays, which were a holdover from the original version. Ran +// through dos2unix. +// +// Revision 1.5 2009-06-16 02:53:58 Nathan +// Changed some signal names for better consistency between different hardware modules. Removed stale CVS log/comments. +// +// Revision 1.4 2009/05/17 20:54:38 Nathan +// Changed email address to opencores.org +// +// Revision 1.3 2008/06/18 18:45:07 Nathan +// Improved reset slightly. Cleanup. +// +// +// Revision 1.2 2008/05/14 13:13:24 Nathan +// Rewrote TAP FSM in canonical form, for readability. Switched +// from one-hot to binary encoding. Made reset signal active- +// low, per JTAG spec. Removed FF chain for 5 TMS reset - reset +// done in Test Logic Reset mode. Added test_logic_reset_o and +// run_test_idle_o signals. Removed double registers from IR data +// path. Unified the registers at the output of each data register +// to a single shared FF. +// + +`include "adbg_tap_defines.v" + +// Top module +module adbg_tap_top( + // JTAG pads + tms_pad_i, + tck_pad_i, + trstn_pad_i, + tdi_pad_i, + tdo_pad_o, + tdo_padoe_o, + + test_mode_i, + + // TAP states + test_logic_reset_o, + run_test_idle_o, + shift_dr_o, + pause_dr_o, + update_dr_o, + capture_dr_o, + + // Select signals for boundary scan or mbist + extest_select_o, + sample_preload_select_o, + mbist_select_o, + debug_select_o, + + // TDO signal that is connected to TDI of sub-modules. + tdi_o, + + // TDI signals from sub-modules + debug_tdo_i, // from debug module + bs_chain_tdo_i, // from Boundary Scan Chain + mbist_tdo_i // from Mbist Chain + ); + + +// JTAG pins +input tms_pad_i; // JTAG test mode select pad +input tck_pad_i; // JTAG test clock pad +input trstn_pad_i; // JTAG test reset pad +input tdi_pad_i; // JTAG test data input pad +output tdo_pad_o; // JTAG test data output pad +output tdo_padoe_o; // Output enable for JTAG test data output pad + +input test_mode_i; // test mode input + +// TAP states +output test_logic_reset_o; +output run_test_idle_o; +output shift_dr_o; +output pause_dr_o; +output update_dr_o; +output capture_dr_o; + +// Select signals for boundary scan or mbist +output extest_select_o; +output sample_preload_select_o; +output mbist_select_o; +output debug_select_o; + +// TDO signal that is connected to TDI of sub-modules. +output tdi_o; + +// TDI signals from sub-modules +input debug_tdo_i; // from debug module +input bs_chain_tdo_i; // from Boundary Scan Chain +input mbist_tdo_i; // from Mbist Chain + +// Wires which depend on the state of the TAP FSM +reg test_logic_reset; +reg run_test_idle; +reg select_dr_scan; +reg capture_dr; +reg shift_dr; +reg exit1_dr; +reg pause_dr; +reg exit2_dr; +reg update_dr; +reg select_ir_scan; +reg capture_ir; +reg shift_ir; +reg exit1_ir; +reg pause_ir; +reg exit2_ir; +reg update_ir; + +// Wires which depend on the current value in the IR +reg extest_select; +reg sample_preload_select; +reg idcode_select; +reg mbist_select; +reg debug_select; +reg bypass_select; + +// TDO and enable +reg tdo_pad_o; +reg tdo_padoe_o; + +wire s_clk_neg; +wire s_tck_inv; + +cluster_clock_inverter u_clk_inv (.clk_i(tck_pad_i), .clk_o(s_tck_inv)); +cluster_clock_mux2 u_clk_mux( + .clk0_i(s_tck_inv), + .clk1_i(tck_pad_i), + .clk_sel_i(test_mode_i), + .clk_o(s_clk_neg) +); + +assign tdi_o = tdi_pad_i; + +assign test_logic_reset_o = test_logic_reset; +assign run_test_idle_o = run_test_idle; +assign shift_dr_o = shift_dr; +assign pause_dr_o = pause_dr; +assign update_dr_o = update_dr; +assign capture_dr_o = capture_dr; + +assign extest_select_o = extest_select; +assign sample_preload_select_o = sample_preload_select; +assign mbist_select_o = mbist_select; +assign debug_select_o = debug_select; + + +/********************************************************************************** +* * +* TAP State Machine: Fully JTAG compliant * +* * +**********************************************************************************/ +// Definition of machine state values. We could one-hot encode this, and use 16 +// registers, but this uses binary encoding for the minimum of 4 DFF's instead. +`define STATE_test_logic_reset 4'hF +`define STATE_run_test_idle 4'hC +`define STATE_select_dr_scan 4'h7 +`define STATE_capture_dr 4'h6 +`define STATE_shift_dr 4'h2 +`define STATE_exit1_dr 4'h1 +`define STATE_pause_dr 4'h3 +`define STATE_exit2_dr 4'h0 +`define STATE_update_dr 4'h5 +`define STATE_select_ir_scan 4'h4 +`define STATE_capture_ir 4'hE +`define STATE_shift_ir 4'hA +`define STATE_exit1_ir 4'h9 +`define STATE_pause_ir 4'hB +`define STATE_exit2_ir 4'h8 +`define STATE_update_ir 4'hD + +reg [3:0] TAP_state; // FIXED NOT POSSIBLE IN SYNTHESIS --> = `STATE_test_logic_reset; // current state of the TAP controller +reg [3:0] next_TAP_state; // state TAP will take at next rising TCK, combinational signal + +// sequential part of the FSM +always @ (posedge tck_pad_i or negedge trstn_pad_i) +begin + if(trstn_pad_i == 0) + TAP_state = `STATE_test_logic_reset; + else + TAP_state = next_TAP_state; +end + + +// Determination of next state; purely combinatorial +always @ (TAP_state or tms_pad_i) +begin + case(TAP_state) + `STATE_test_logic_reset: + begin + if(tms_pad_i) next_TAP_state = `STATE_test_logic_reset; + else next_TAP_state = `STATE_run_test_idle; + end + `STATE_run_test_idle: + begin + if(tms_pad_i) next_TAP_state = `STATE_select_dr_scan; + else next_TAP_state = `STATE_run_test_idle; + end + `STATE_select_dr_scan: + begin + if(tms_pad_i) next_TAP_state = `STATE_select_ir_scan; + else next_TAP_state = `STATE_capture_dr; + end + `STATE_capture_dr: + begin + if(tms_pad_i) next_TAP_state = `STATE_exit1_dr; + else next_TAP_state = `STATE_shift_dr; + end + `STATE_shift_dr: + begin + if(tms_pad_i) next_TAP_state = `STATE_exit1_dr; + else next_TAP_state = `STATE_shift_dr; + end + `STATE_exit1_dr: + begin + if(tms_pad_i) next_TAP_state = `STATE_update_dr; + else next_TAP_state = `STATE_pause_dr; + end + `STATE_pause_dr: + begin + if(tms_pad_i) next_TAP_state = `STATE_exit2_dr; + else next_TAP_state = `STATE_pause_dr; + end + `STATE_exit2_dr: + begin + if(tms_pad_i) next_TAP_state = `STATE_update_dr; + else next_TAP_state = `STATE_shift_dr; + end + `STATE_update_dr: + begin + if(tms_pad_i) next_TAP_state = `STATE_select_dr_scan; + else next_TAP_state = `STATE_run_test_idle; + end + `STATE_select_ir_scan: + begin + if(tms_pad_i) next_TAP_state = `STATE_test_logic_reset; + else next_TAP_state = `STATE_capture_ir; + end + `STATE_capture_ir: + begin + if(tms_pad_i) next_TAP_state = `STATE_exit1_ir; + else next_TAP_state = `STATE_shift_ir; + end + `STATE_shift_ir: + begin + if(tms_pad_i) next_TAP_state = `STATE_exit1_ir; + else next_TAP_state = `STATE_shift_ir; + end + `STATE_exit1_ir: + begin + if(tms_pad_i) next_TAP_state = `STATE_update_ir; + else next_TAP_state = `STATE_pause_ir; + end + `STATE_pause_ir: + begin + if(tms_pad_i) next_TAP_state = `STATE_exit2_ir; + else next_TAP_state = `STATE_pause_ir; + end + `STATE_exit2_ir: + begin + if(tms_pad_i) next_TAP_state = `STATE_update_ir; + else next_TAP_state = `STATE_shift_ir; + end + `STATE_update_ir: + begin + if(tms_pad_i) next_TAP_state = `STATE_select_dr_scan; + else next_TAP_state = `STATE_run_test_idle; + end + default: next_TAP_state = `STATE_test_logic_reset; // can't actually happen + endcase +end + + +// Outputs of state machine, pure combinatorial +always @ (TAP_state) +begin + // Default everything to 0, keeps the case statement simple + test_logic_reset = 1'b0; + run_test_idle = 1'b0; + select_dr_scan = 1'b0; + capture_dr = 1'b0; + shift_dr = 1'b0; + exit1_dr = 1'b0; + pause_dr = 1'b0; + exit2_dr = 1'b0; + update_dr = 1'b0; + select_ir_scan = 1'b0; + capture_ir = 1'b0; + shift_ir = 1'b0; + exit1_ir = 1'b0; + pause_ir = 1'b0; + exit2_ir = 1'b0; + update_ir = 1'b0; + + case(TAP_state) + `STATE_test_logic_reset: test_logic_reset = 1'b1; + `STATE_run_test_idle: run_test_idle = 1'b1; + `STATE_select_dr_scan: select_dr_scan = 1'b1; + `STATE_capture_dr: capture_dr = 1'b1; + `STATE_shift_dr: shift_dr = 1'b1; + `STATE_exit1_dr: exit1_dr = 1'b1; + `STATE_pause_dr: pause_dr = 1'b1; + `STATE_exit2_dr: exit2_dr = 1'b1; + `STATE_update_dr: update_dr = 1'b1; + `STATE_select_ir_scan: select_ir_scan = 1'b1; + `STATE_capture_ir: capture_ir = 1'b1; + `STATE_shift_ir: shift_ir = 1'b1; + `STATE_exit1_ir: exit1_ir = 1'b1; + `STATE_pause_ir: pause_ir = 1'b1; + `STATE_exit2_ir: exit2_ir = 1'b1; + `STATE_update_ir: update_ir = 1'b1; + default: ; + endcase +end + +/********************************************************************************** +* * +* End: TAP State Machine * +* * +**********************************************************************************/ + + + +/********************************************************************************** +* * +* jtag_ir: JTAG Instruction Register * +* * +**********************************************************************************/ +reg [`IR_LENGTH-1:0] jtag_ir; // Instruction register +reg [`IR_LENGTH-1:0] latched_jtag_ir; //, latched_jtag_ir_neg; +wire instruction_tdo; + +always @ (posedge tck_pad_i or negedge trstn_pad_i) +begin + if(trstn_pad_i == 0) + jtag_ir[`IR_LENGTH-1:0] <= `IR_LENGTH'b0; + else if (test_logic_reset == 1) + jtag_ir[`IR_LENGTH-1:0] <= `IR_LENGTH'b0; + else if(capture_ir) + jtag_ir <= 4'b0101; // This value is fixed for easier fault detection + else if(shift_ir) + jtag_ir[`IR_LENGTH-1:0] <= {tdi_pad_i, jtag_ir[`IR_LENGTH-1:1]}; +end + +assign instruction_tdo = jtag_ir[0]; // This is latched on a negative TCK edge after the output MUX + +// Updating jtag_ir (Instruction Register) +// jtag_ir should be latched on FALLING EDGE of TCK when capture_ir == 1 +always @ (posedge s_clk_neg or negedge trstn_pad_i) +begin + if(trstn_pad_i == 0) + latched_jtag_ir <= `IDCODE; // IDCODE selected after reset + else if (test_logic_reset) + latched_jtag_ir <= `IDCODE; // IDCODE selected after reset + else if(update_ir) + latched_jtag_ir <= jtag_ir; +end + +/********************************************************************************** +* * +* End: jtag_ir * +* * +**********************************************************************************/ + + + +/********************************************************************************** +* * +* idcode logic * +* * +**********************************************************************************/ +reg [31:0] idcode_reg; +wire idcode_tdo; + +always @ (posedge tck_pad_i or negedge trstn_pad_i) +begin + if(trstn_pad_i == 0) + idcode_reg <= `IDCODE_VALUE; // IDCODE selected after reset + else if (test_logic_reset) + idcode_reg <= `IDCODE_VALUE; // IDCODE selected after reset + else if(idcode_select & capture_dr) + idcode_reg <= `IDCODE_VALUE; + else if(idcode_select & shift_dr) + idcode_reg <= {tdi_pad_i, idcode_reg[31:1]}; + +end + +assign idcode_tdo = idcode_reg[0]; // This is latched on a negative TCK edge after the output MUX + +/********************************************************************************** +* * +* End: idcode logic * +* * +**********************************************************************************/ + + +/********************************************************************************** +* * +* Bypass logic * +* * +**********************************************************************************/ +wire bypassed_tdo; +reg bypass_reg; // This is a 1-bit register + +always @ (posedge tck_pad_i or negedge trstn_pad_i) +begin + if (trstn_pad_i == 0) + bypass_reg <= 1'b0; + else if (test_logic_reset == 1) + bypass_reg <= 1'b0; + else if (bypass_select & capture_dr) + bypass_reg<= 1'b0; + else if(bypass_select & shift_dr) + bypass_reg<= tdi_pad_i; +end + +assign bypassed_tdo = bypass_reg; // This is latched on a negative TCK edge after the output MUX + +/********************************************************************************** +* * +* End: Bypass logic * +* * +**********************************************************************************/ + + +/********************************************************************************** +* * +* Selecting active data register * +* * +**********************************************************************************/ +always @ (latched_jtag_ir) +begin + extest_select = 1'b0; + sample_preload_select = 1'b0; + idcode_select = 1'b0; + mbist_select = 1'b0; + debug_select = 1'b0; + bypass_select = 1'b0; + + case(latched_jtag_ir) /* synthesis parallel_case */ + `EXTEST: extest_select = 1'b1; // External test + `SAMPLE_PRELOAD: sample_preload_select = 1'b1; // Sample preload + `IDCODE: idcode_select = 1'b1; // ID Code + `MBIST: mbist_select = 1'b1; // Mbist test + `DEBUG: debug_select = 1'b1; // Debug + `BYPASS: bypass_select = 1'b1; // BYPASS + default: bypass_select = 1'b1; // BYPASS + endcase +end + + +/********************************************************************************** +* * +* Multiplexing TDO data * +* * +**********************************************************************************/ +reg tdo_mux_out; // really just a wire + +always @ (shift_ir or instruction_tdo or latched_jtag_ir or idcode_tdo or + debug_tdo_i or bs_chain_tdo_i or mbist_tdo_i or bypassed_tdo or + bs_chain_tdo_i) +begin + if(shift_ir) + tdo_mux_out = instruction_tdo; + else + begin + case(latched_jtag_ir) // synthesis parallel_case + `IDCODE: tdo_mux_out = idcode_tdo; // Reading ID code + `DEBUG: tdo_mux_out = debug_tdo_i; // Debug + `SAMPLE_PRELOAD: tdo_mux_out = bs_chain_tdo_i; // Sampling/Preloading + `EXTEST: tdo_mux_out = bs_chain_tdo_i; // External test + `MBIST: tdo_mux_out = mbist_tdo_i; // Mbist test + default: tdo_mux_out = bypassed_tdo; // BYPASS instruction + endcase + end +end + + +// TDO changes state at negative edge of TCK +always @ (posedge s_clk_neg or negedge trstn_pad_i) +begin + if (trstn_pad_i == 0) + tdo_pad_o <= 1'b0; + else + tdo_pad_o <= tdo_mux_out; +end + + +// Tristate control for tdo_pad_o pin +always @ (posedge s_clk_neg or negedge trstn_pad_i) +begin + if (trstn_pad_i == 0) + tdo_padoe_o <= 1'b0; + else + tdo_padoe_o <= shift_ir | shift_dr; +end +/********************************************************************************** +* * +* End: Multiplexing TDO data * +* * +**********************************************************************************/ + +endmodule
diff --git a/verilog/rtl/ips/adv_dbg_if/rtl/adbg_top.v b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_top.v new file mode 100644 index 0000000..b133af2 --- /dev/null +++ b/verilog/rtl/ips/adv_dbg_if/rtl/adbg_top.v
@@ -0,0 +1,264 @@ +module adbg_top +#( + parameter NB_CORES = 4, + parameter AXI_ADDR_WIDTH = 32, + parameter AXI_DATA_WIDTH = 64, + parameter AXI_USER_WIDTH = 6, + parameter AXI_ID_WIDTH = 3 +) +( + tck_i, + tdi_i, + tdo_o, + trstn_i, + shift_dr_i, + pause_dr_i, + update_dr_i, + capture_dr_i, + debug_select_i, + cpu_addr_o, + cpu_data_i, + cpu_data_o, + cpu_bp_i, + cpu_stall_o, + cpu_stb_o, + cpu_we_o, + cpu_ack_i, + cpu_rst_o, + axi_aclk, + axi_aresetn, + axi_master_aw_valid, + axi_master_aw_addr, + axi_master_aw_prot, + axi_master_aw_region, + axi_master_aw_len, + axi_master_aw_size, + axi_master_aw_burst, + axi_master_aw_lock, + axi_master_aw_cache, + axi_master_aw_qos, + axi_master_aw_id, + axi_master_aw_user, + axi_master_aw_ready, + axi_master_ar_valid, + axi_master_ar_addr, + axi_master_ar_prot, + axi_master_ar_region, + axi_master_ar_len, + axi_master_ar_size, + axi_master_ar_burst, + axi_master_ar_lock, + axi_master_ar_cache, + axi_master_ar_qos, + axi_master_ar_id, + axi_master_ar_user, + axi_master_ar_ready, + axi_master_w_valid, + axi_master_w_data, + axi_master_w_strb, + axi_master_w_user, + axi_master_w_last, + axi_master_w_ready, + axi_master_r_valid, + axi_master_r_data, + axi_master_r_resp, + axi_master_r_last, + axi_master_r_id, + axi_master_r_user, + axi_master_r_ready, + axi_master_b_valid, + axi_master_b_resp, + axi_master_b_id, + axi_master_b_user, + axi_master_b_ready +); + //parameter NB_CORES = 4; + //parameter AXI_ADDR_WIDTH = 32; + //parameter AXI_DATA_WIDTH = 64; + //parameter AXI_USER_WIDTH = 6; + //parameter AXI_ID_WIDTH = 3; + input wire tck_i; + input wire tdi_i; + output reg tdo_o; + input wire trstn_i; + input wire shift_dr_i; + input wire pause_dr_i; + input wire update_dr_i; + input wire capture_dr_i; + input wire debug_select_i; + output wire [(NB_CORES * 16) - 1:0] cpu_addr_o; + input wire [(NB_CORES * 32) - 1:0] cpu_data_i; + output wire [(NB_CORES * 32) - 1:0] cpu_data_o; + input wire [NB_CORES - 1:0] cpu_bp_i; + output wire [NB_CORES - 1:0] cpu_stall_o; + output wire [NB_CORES - 1:0] cpu_stb_o; + output wire [NB_CORES - 1:0] cpu_we_o; + input wire [NB_CORES - 1:0] cpu_ack_i; + output wire [NB_CORES - 1:0] cpu_rst_o; + input wire axi_aclk; + input wire axi_aresetn; + output wire axi_master_aw_valid; + output wire [AXI_ADDR_WIDTH - 1:0] axi_master_aw_addr; + output wire [2:0] axi_master_aw_prot; + output wire [3:0] axi_master_aw_region; + output wire [7:0] axi_master_aw_len; + output wire [2:0] axi_master_aw_size; + output wire [1:0] axi_master_aw_burst; + output wire axi_master_aw_lock; + output wire [3:0] axi_master_aw_cache; + output wire [3:0] axi_master_aw_qos; + output wire [AXI_ID_WIDTH - 1:0] axi_master_aw_id; + output wire [AXI_USER_WIDTH - 1:0] axi_master_aw_user; + input wire axi_master_aw_ready; + output wire axi_master_ar_valid; + output wire [AXI_ADDR_WIDTH - 1:0] axi_master_ar_addr; + output wire [2:0] axi_master_ar_prot; + output wire [3:0] axi_master_ar_region; + output wire [7:0] axi_master_ar_len; + output wire [2:0] axi_master_ar_size; + output wire [1:0] axi_master_ar_burst; + output wire axi_master_ar_lock; + output wire [3:0] axi_master_ar_cache; + output wire [3:0] axi_master_ar_qos; + output wire [AXI_ID_WIDTH - 1:0] axi_master_ar_id; + output wire [AXI_USER_WIDTH - 1:0] axi_master_ar_user; + input wire axi_master_ar_ready; + output wire axi_master_w_valid; + output wire [AXI_DATA_WIDTH - 1:0] axi_master_w_data; + output wire [(AXI_DATA_WIDTH / 8) - 1:0] axi_master_w_strb; + output wire [AXI_USER_WIDTH - 1:0] axi_master_w_user; + output wire axi_master_w_last; + input wire axi_master_w_ready; + input wire axi_master_r_valid; + input wire [AXI_DATA_WIDTH - 1:0] axi_master_r_data; + input wire [1:0] axi_master_r_resp; + input wire axi_master_r_last; + input wire [AXI_ID_WIDTH - 1:0] axi_master_r_id; + input wire [AXI_USER_WIDTH - 1:0] axi_master_r_user; + output wire axi_master_r_ready; + input wire axi_master_b_valid; + input wire [1:0] axi_master_b_resp; + input wire [AXI_ID_WIDTH - 1:0] axi_master_b_id; + input wire [AXI_USER_WIDTH - 1:0] axi_master_b_user; + output wire axi_master_b_ready; + wire tdo_axi; + wire tdo_cpu; + reg [63:0] input_shift_reg; + reg [4:0] module_id_reg; + wire select_cmd; + wire [4:0] module_id_in; + reg [1:0] module_selects; + wire select_inhibit; + wire [1:0] module_inhibit; + integer j; + assign select_cmd = input_shift_reg[63]; + assign module_id_in = input_shift_reg[62:58]; + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + module_id_reg <= 5'h00; + else if (((debug_select_i && select_cmd) && update_dr_i) && !select_inhibit) + module_id_reg <= module_id_in; + always @(*) + if (module_id_reg == 0) + module_selects = 2'b01; + else + module_selects = 2'b10; + always @(posedge tck_i or negedge trstn_i) + if (~trstn_i) + input_shift_reg <= 'h0; + else if (debug_select_i && shift_dr_i) + input_shift_reg <= {tdi_i, input_shift_reg[63:1]}; + adbg_axi_module #( + .AXI_ADDR_WIDTH(AXI_ADDR_WIDTH), + .AXI_DATA_WIDTH(AXI_DATA_WIDTH), + .AXI_USER_WIDTH(AXI_USER_WIDTH), + .AXI_ID_WIDTH(AXI_ID_WIDTH) + ) i_dbg_axi( + .tck_i(tck_i), + .module_tdo_o(tdo_axi), + .tdi_i(tdi_i), + .capture_dr_i(capture_dr_i), + .shift_dr_i(shift_dr_i), + .update_dr_i(update_dr_i), + .data_register_i(input_shift_reg), + .module_select_i(module_selects[0]), + .top_inhibit_o(module_inhibit[0]), + .trstn_i(trstn_i), + .axi_aclk(axi_aclk), + .axi_aresetn(axi_aresetn), + .axi_master_aw_valid(axi_master_aw_valid), + .axi_master_aw_addr(axi_master_aw_addr), + .axi_master_aw_prot(axi_master_aw_prot), + .axi_master_aw_region(axi_master_aw_region), + .axi_master_aw_len(axi_master_aw_len), + .axi_master_aw_size(axi_master_aw_size), + .axi_master_aw_burst(axi_master_aw_burst), + .axi_master_aw_lock(axi_master_aw_lock), + .axi_master_aw_cache(axi_master_aw_cache), + .axi_master_aw_qos(axi_master_aw_qos), + .axi_master_aw_id(axi_master_aw_id), + .axi_master_aw_user(axi_master_aw_user), + .axi_master_aw_ready(axi_master_aw_ready), + .axi_master_ar_valid(axi_master_ar_valid), + .axi_master_ar_addr(axi_master_ar_addr), + .axi_master_ar_prot(axi_master_ar_prot), + .axi_master_ar_region(axi_master_ar_region), + .axi_master_ar_len(axi_master_ar_len), + .axi_master_ar_size(axi_master_ar_size), + .axi_master_ar_burst(axi_master_ar_burst), + .axi_master_ar_lock(axi_master_ar_lock), + .axi_master_ar_cache(axi_master_ar_cache), + .axi_master_ar_qos(axi_master_ar_qos), + .axi_master_ar_id(axi_master_ar_id), + .axi_master_ar_user(axi_master_ar_user), + .axi_master_ar_ready(axi_master_ar_ready), + .axi_master_w_valid(axi_master_w_valid), + .axi_master_w_data(axi_master_w_data), + .axi_master_w_strb(axi_master_w_strb), + .axi_master_w_user(axi_master_w_user), + .axi_master_w_last(axi_master_w_last), + .axi_master_w_ready(axi_master_w_ready), + .axi_master_r_valid(axi_master_r_valid), + .axi_master_r_data(axi_master_r_data), + .axi_master_r_resp(axi_master_r_resp), + .axi_master_r_last(axi_master_r_last), + .axi_master_r_id(axi_master_r_id), + .axi_master_r_user(axi_master_r_user), + .axi_master_r_ready(axi_master_r_ready), + .axi_master_b_valid(axi_master_b_valid), + .axi_master_b_resp(axi_master_b_resp), + .axi_master_b_id(axi_master_b_id), + .axi_master_b_user(axi_master_b_user), + .axi_master_b_ready(axi_master_b_ready) + ); + adbg_or1k_module #(.NB_CORES(NB_CORES)) i_dbg_cpu_or1k( + .tck_i(tck_i), + .module_tdo_o(tdo_cpu), + .tdi_i(tdi_i), + .capture_dr_i(capture_dr_i), + .shift_dr_i(shift_dr_i), + .update_dr_i(update_dr_i), + .data_register_i(input_shift_reg[63:7]), + .module_select_i(module_selects[1]), + .top_inhibit_o(module_inhibit[1]), + .trstn_i(trstn_i), + .cpu_clk_i(axi_aclk), + .cpu_rstn_i(axi_aresetn), + .cpu_addr_o(cpu_addr_o), + .cpu_data_i(cpu_data_i), + .cpu_data_o(cpu_data_o), + .cpu_bp_i(cpu_bp_i), + .cpu_stall_o(cpu_stall_o), + .cpu_stb_o(cpu_stb_o), + .cpu_we_o(cpu_we_o), + .cpu_ack_i(cpu_ack_i) + ); + assign select_inhibit = |module_inhibit; + always @(module_id_reg or tdo_axi or tdo_cpu) + if (module_id_reg == 0) + tdo_o <= tdo_axi; + else if (module_id_reg == 1) + tdo_o <= tdo_cpu; + else + tdo_o <= 1'b0; +endmodule
diff --git a/verilog/rtl/ips/adv_dbg_if/rtl/adv_dbg_if.v b/verilog/rtl/ips/adv_dbg_if/rtl/adv_dbg_if.v new file mode 100644 index 0000000..8c5d5bb --- /dev/null +++ b/verilog/rtl/ips/adv_dbg_if/rtl/adv_dbg_if.v
@@ -0,0 +1,249 @@ +module adv_dbg_if +#( + parameter NB_CORES = 4, + parameter AXI_ADDR_WIDTH = 32, + parameter AXI_DATA_WIDTH = 64, + parameter AXI_USER_WIDTH = 6, + parameter AXI_ID_WIDTH = 3 +) +( + tms_pad_i, + tck_pad_i, + trstn_pad_i, + tdi_pad_i, + tdo_pad_o, + tdo_padoe_o, + test_mode_i, + cpu_clk_i, + cpu_addr_o, + cpu_data_i, + cpu_data_o, + cpu_bp_i, + cpu_stall_o, + cpu_stb_o, + cpu_we_o, + cpu_ack_i, + cpu_rst_o, + axi_aclk, + axi_aresetn, + axi_master_aw_valid, + axi_master_aw_addr, + axi_master_aw_prot, + axi_master_aw_region, + axi_master_aw_len, + axi_master_aw_size, + axi_master_aw_burst, + axi_master_aw_lock, + axi_master_aw_cache, + axi_master_aw_qos, + axi_master_aw_id, + axi_master_aw_user, + axi_master_aw_ready, + axi_master_ar_valid, + axi_master_ar_addr, + axi_master_ar_prot, + axi_master_ar_region, + axi_master_ar_len, + axi_master_ar_size, + axi_master_ar_burst, + axi_master_ar_lock, + axi_master_ar_cache, + axi_master_ar_qos, + axi_master_ar_id, + axi_master_ar_user, + axi_master_ar_ready, + axi_master_w_valid, + axi_master_w_data, + axi_master_w_strb, + axi_master_w_user, + axi_master_w_last, + axi_master_w_ready, + axi_master_r_valid, + axi_master_r_data, + axi_master_r_resp, + axi_master_r_last, + axi_master_r_id, + axi_master_r_user, + axi_master_r_ready, + axi_master_b_valid, + axi_master_b_resp, + axi_master_b_id, + axi_master_b_user, + axi_master_b_ready +); + //parameter NB_CORES = 4; + //parameter AXI_ADDR_WIDTH = 32; + //parameter AXI_DATA_WIDTH = 64; + //parameter AXI_USER_WIDTH = 6; + //parameter AXI_ID_WIDTH = 3; + input wire tms_pad_i; + input wire tck_pad_i; + input wire trstn_pad_i; + input wire tdi_pad_i; + output wire tdo_pad_o; + output wire tdo_padoe_o; + input wire test_mode_i; + input wire [NB_CORES - 1:0] cpu_clk_i; + output wire [(NB_CORES * 16) - 1:0] cpu_addr_o; + input wire [(NB_CORES * 32) - 1:0] cpu_data_i; + output wire [(NB_CORES * 32) - 1:0] cpu_data_o; + input wire [NB_CORES - 1:0] cpu_bp_i; + output wire [NB_CORES - 1:0] cpu_stall_o; + output wire [NB_CORES - 1:0] cpu_stb_o; + output wire [NB_CORES - 1:0] cpu_we_o; + input wire [NB_CORES - 1:0] cpu_ack_i; + output wire [NB_CORES - 1:0] cpu_rst_o; + input wire axi_aclk; + input wire axi_aresetn; + output wire axi_master_aw_valid; + output wire [AXI_ADDR_WIDTH - 1:0] axi_master_aw_addr; + output wire [2:0] axi_master_aw_prot; + output wire [3:0] axi_master_aw_region; + output wire [7:0] axi_master_aw_len; + output wire [2:0] axi_master_aw_size; + output wire [1:0] axi_master_aw_burst; + output wire axi_master_aw_lock; + output wire [3:0] axi_master_aw_cache; + output wire [3:0] axi_master_aw_qos; + output wire [AXI_ID_WIDTH - 1:0] axi_master_aw_id; + output wire [AXI_USER_WIDTH - 1:0] axi_master_aw_user; + input wire axi_master_aw_ready; + output wire axi_master_ar_valid; + output wire [AXI_ADDR_WIDTH - 1:0] axi_master_ar_addr; + output wire [2:0] axi_master_ar_prot; + output wire [3:0] axi_master_ar_region; + output wire [7:0] axi_master_ar_len; + output wire [2:0] axi_master_ar_size; + output wire [1:0] axi_master_ar_burst; + output wire axi_master_ar_lock; + output wire [3:0] axi_master_ar_cache; + output wire [3:0] axi_master_ar_qos; + output wire [AXI_ID_WIDTH - 1:0] axi_master_ar_id; + output wire [AXI_USER_WIDTH - 1:0] axi_master_ar_user; + input wire axi_master_ar_ready; + output wire axi_master_w_valid; + output wire [AXI_DATA_WIDTH - 1:0] axi_master_w_data; + output wire [(AXI_DATA_WIDTH / 8) - 1:0] axi_master_w_strb; + output wire [AXI_USER_WIDTH - 1:0] axi_master_w_user; + output wire axi_master_w_last; + input wire axi_master_w_ready; + input wire axi_master_r_valid; + input wire [AXI_DATA_WIDTH - 1:0] axi_master_r_data; + input wire [1:0] axi_master_r_resp; + input wire axi_master_r_last; + input wire [AXI_ID_WIDTH - 1:0] axi_master_r_id; + input wire [AXI_USER_WIDTH - 1:0] axi_master_r_user; + output wire axi_master_r_ready; + input wire axi_master_b_valid; + input wire [1:0] axi_master_b_resp; + input wire [AXI_ID_WIDTH - 1:0] axi_master_b_id; + input wire [AXI_USER_WIDTH - 1:0] axi_master_b_user; + output wire axi_master_b_ready; + wire s_test_logic_reset; + wire s_run_test_idle; + wire s_shift_dr; + wire s_pause_dr; + wire s_update_dr; + wire s_capture_dr; + wire s_extest_select; + wire s_sample_preload_select; + wire s_mbist_select; + wire s_debug_select; + wire s_tdi; + wire s_debug_tdo; + adbg_tap_top cluster_tap_i( + .tms_pad_i(tms_pad_i), + .tck_pad_i(tck_pad_i), + .trstn_pad_i(trstn_pad_i), + .tdi_pad_i(tdi_pad_i), + .tdo_pad_o(tdo_pad_o), + .tdo_padoe_o(tdo_padoe_o), + .test_mode_i(test_mode_i), + .test_logic_reset_o(s_test_logic_reset), + .run_test_idle_o(s_run_test_idle), + .shift_dr_o(s_shift_dr), + .pause_dr_o(s_pause_dr), + .update_dr_o(s_update_dr), + .capture_dr_o(s_capture_dr), + .extest_select_o(s_extest_select), + .sample_preload_select_o(s_sample_preload_select), + .mbist_select_o(s_mbist_select), + .debug_select_o(s_debug_select), + .tdi_o(s_tdi), + .debug_tdo_i(s_debug_tdo), + .bs_chain_tdo_i(1'b0), + .mbist_tdo_i(1'b0) + ); + adbg_top #( + .NB_CORES(NB_CORES), + .AXI_ADDR_WIDTH(AXI_ADDR_WIDTH), + .AXI_DATA_WIDTH(AXI_DATA_WIDTH), + .AXI_USER_WIDTH(AXI_USER_WIDTH), + .AXI_ID_WIDTH(AXI_ID_WIDTH) + ) dbg_module_i( + .tck_i(tck_pad_i), + .tdi_i(s_tdi), + .tdo_o(s_debug_tdo), + .trstn_i(trstn_pad_i), + .shift_dr_i(s_shift_dr), + .pause_dr_i(s_pause_dr), + .update_dr_i(s_update_dr), + .capture_dr_i(s_capture_dr), + .debug_select_i(s_debug_select), + .cpu_addr_o(cpu_addr_o), + .cpu_data_i(cpu_data_i), + .cpu_data_o(cpu_data_o), + .cpu_bp_i(cpu_bp_i), + .cpu_stall_o(cpu_stall_o), + .cpu_stb_o(cpu_stb_o), + .cpu_we_o(cpu_we_o), + .cpu_ack_i(cpu_ack_i), + .cpu_rst_o(cpu_rst_o), + .axi_aclk(axi_aclk), + .axi_aresetn(axi_aresetn), + .axi_master_aw_valid(axi_master_aw_valid), + .axi_master_aw_addr(axi_master_aw_addr), + .axi_master_aw_prot(axi_master_aw_prot), + .axi_master_aw_region(axi_master_aw_region), + .axi_master_aw_len(axi_master_aw_len), + .axi_master_aw_size(axi_master_aw_size), + .axi_master_aw_burst(axi_master_aw_burst), + .axi_master_aw_lock(axi_master_aw_lock), + .axi_master_aw_cache(axi_master_aw_cache), + .axi_master_aw_qos(axi_master_aw_qos), + .axi_master_aw_id(axi_master_aw_id), + .axi_master_aw_user(axi_master_aw_user), + .axi_master_aw_ready(axi_master_aw_ready), + .axi_master_ar_valid(axi_master_ar_valid), + .axi_master_ar_addr(axi_master_ar_addr), + .axi_master_ar_prot(axi_master_ar_prot), + .axi_master_ar_region(axi_master_ar_region), + .axi_master_ar_len(axi_master_ar_len), + .axi_master_ar_size(axi_master_ar_size), + .axi_master_ar_burst(axi_master_ar_burst), + .axi_master_ar_lock(axi_master_ar_lock), + .axi_master_ar_cache(axi_master_ar_cache), + .axi_master_ar_qos(axi_master_ar_qos), + .axi_master_ar_id(axi_master_ar_id), + .axi_master_ar_user(axi_master_ar_user), + .axi_master_ar_ready(axi_master_ar_ready), + .axi_master_w_valid(axi_master_w_valid), + .axi_master_w_data(axi_master_w_data), + .axi_master_w_strb(axi_master_w_strb), + .axi_master_w_user(axi_master_w_user), + .axi_master_w_last(axi_master_w_last), + .axi_master_w_ready(axi_master_w_ready), + .axi_master_r_valid(axi_master_r_valid), + .axi_master_r_data(axi_master_r_data), + .axi_master_r_resp(axi_master_r_resp), + .axi_master_r_last(axi_master_r_last), + .axi_master_r_id(axi_master_r_id), + .axi_master_r_user(axi_master_r_user), + .axi_master_r_ready(axi_master_r_ready), + .axi_master_b_valid(axi_master_b_valid), + .axi_master_b_resp(axi_master_b_resp), + .axi_master_b_id(axi_master_b_id), + .axi_master_b_user(axi_master_b_user), + .axi_master_b_ready(axi_master_b_ready) + ); +endmodule
diff --git a/verilog/rtl/ips/adv_dbg_if/rtl/bytefifo.v b/verilog/rtl/ips/adv_dbg_if/rtl/bytefifo.v new file mode 100644 index 0000000..ab3dc4e --- /dev/null +++ b/verilog/rtl/ips/adv_dbg_if/rtl/bytefifo.v
@@ -0,0 +1,225 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// bytefifo.v //// +//// //// +//// //// +//// A simple byte-wide FIFO with byte and free space counts //// +//// //// +//// Author(s): //// +//// Nathan Yawn (nathan.yawn@opencores.org) //// +//// //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2010 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source 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 Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// This is an 8-entry, byte-wide, single-port FIFO. It can either +// push or pop a byte each clock cycle (but not both). It includes +// outputs indicating the number of bytes in the FIFO, and the number +// of bytes free - if you don't connect BYTES_FREE, the synthesis +// tool should eliminate the hardware to generate it. +// +// This attempts to use few resources. There is only 1 counter, +// and only 1 decoder. The FIFO works like a big shift register: +// bytes are always written to entry '0' of the FIFO, and older +// bytes are shifted toward entry '7' as newer bytes are added. +// The counter determines which entry the output reads. +// +// One caveat is that the DATA_OUT will glitch during a 'push' +// operation. If the output is being sent to another clock +// domain, you should register it first. +// +// Ports: +// CLK: Clock for all synchronous elements +// RST: Zeros the counter and all registers asynchronously +// DATA_IN: Data to be pushed into the FIFO +// DATA_OUT: Always shows the data at the head of the FIFO, 'XX' if empty +// PUSH_POPn: When high (and EN is high), DATA_IN will be pushed onto the +// FIFO and the count will be incremented at the next posedge +// of CLK (assuming the FIFO is not full). When low (and EN +// is high), the count will be decremented and the output changed +// to the next value in the FIFO (assuming FIFO not empty). +// EN: When high at posedege CLK, a push or pop operation will be performed, +// based on the value of PUSH_POPn, assuming sufficient data or space. +// BYTES_AVAIL: Number of bytes in the FIFO. May be in the range 0 to 8. +// BYTES_FREE: Free space in the FIFO. May be in the range 0 to 8. + + +// Top module +module bytefifo ( + CLK, + RSTN, + DATA_IN, + DATA_OUT, + PUSH_POPn, + EN, + BYTES_AVAIL, + BYTES_FREE + ); + + + input CLK; + input RSTN; + input [7:0] DATA_IN; + output [7:0] DATA_OUT; + input PUSH_POPn; + input EN; + output [3:0] BYTES_AVAIL; + output [3:0] BYTES_FREE; + + reg [7:0] reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7; + reg [3:0] counter; + + reg [7:0] DATA_OUT; + wire [3:0] BYTES_AVAIL; + wire [3:0] BYTES_FREE; + wire push_ok; + wire pop_ok; + + /////////////////////////////////// + // Combinatorial assignments + + assign BYTES_AVAIL = counter; + assign BYTES_FREE = 4'h8 - BYTES_AVAIL; + assign push_ok = !(counter == 4'h8); + assign pop_ok = !(counter == 4'h0); + + /////////////////////////////////// + // FIFO memory / shift registers + + // Reg 0 - takes input from DATA_IN + always @ (posedge CLK or negedge RSTN) + begin + if(~RSTN) + reg0 <= 8'h0; + else if(EN & PUSH_POPn & push_ok) + reg0 <= DATA_IN; + end + + + // Reg 1 - takes input from reg0 + always @ (posedge CLK or negedge RSTN) + begin + if(~RSTN) + reg1 <= 8'h0; + else if(EN & PUSH_POPn & push_ok) + reg1 <= reg0; + end + + + // Reg 2 - takes input from reg1 + always @ (posedge CLK or negedge RSTN) + begin + if(~RSTN) + reg2 <= 8'h0; + else if(EN & PUSH_POPn & push_ok) + reg2 <= reg1; + end + + + // Reg 3 - takes input from reg2 + always @ (posedge CLK or negedge RSTN) + begin + if(~RSTN) + reg3 <= 8'h0; + else if(EN & PUSH_POPn & push_ok) + reg3 <= reg2; + end + + + // Reg 4 - takes input from reg3 + always @ (posedge CLK or negedge RSTN) + begin + if(~RSTN) + reg4 <= 8'h0; + else if(EN & PUSH_POPn & push_ok) + reg4 <= reg3; + end + + + // Reg 5 - takes input from reg4 + always @ (posedge CLK or negedge RSTN) + begin + if(~RSTN) + reg5 <= 8'h0; + else if(EN & PUSH_POPn & push_ok) + reg5 <= reg4; + end + + + // Reg 6 - takes input from reg5 + always @ (posedge CLK or negedge RSTN) + begin + if(~RSTN) + reg6 <= 8'h0; + else if(EN & PUSH_POPn & push_ok) + reg6 <= reg5; + end + + + // Reg 7 - takes input from reg6 + always @ (posedge CLK or negedge RSTN) + begin + if(~RSTN) + reg7 <= 8'h0; + else if(EN & PUSH_POPn & push_ok) + reg7 <= reg6; + end + + /////////////////////////////////////////////////// + // Read counter + // This is a 4-bit saturating up/down counter + // The 'saturating' is done via push_ok and pop_ok + + always @ (posedge CLK or negedge RSTN) + begin + if(~RSTN) counter <= 4'h0; + else if(EN & PUSH_POPn & push_ok) counter <= counter + 4'h1; + else if(EN & (~PUSH_POPn) & pop_ok) counter <= counter - 4'h1; + end + + ///////////////////////////////////////////////// + // Output decoder + + always @ (counter or reg0 or reg1 or reg2 or reg3 or reg4 or reg5 + or reg6 or reg7) + begin + case (counter) + 4'h1: DATA_OUT <= reg0; + 4'h2: DATA_OUT <= reg1; + 4'h3: DATA_OUT <= reg2; + 4'h4: DATA_OUT <= reg3; + 4'h5: DATA_OUT <= reg4; + 4'h6: DATA_OUT <= reg5; + 4'h7: DATA_OUT <= reg6; + 4'h8: DATA_OUT <= reg7; + default: DATA_OUT <= 8'hXX; + endcase + end + + +endmodule
diff --git a/verilog/rtl/ips/adv_dbg_if/rtl/syncflop.v b/verilog/rtl/ips/adv_dbg_if/rtl/syncflop.v new file mode 100644 index 0000000..e6a8d56 --- /dev/null +++ b/verilog/rtl/ips/adv_dbg_if/rtl/syncflop.v
@@ -0,0 +1,126 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// syncflop.v //// +//// //// +//// //// +//// A generic synchronization device between two clock domains //// +//// //// +//// Author(s): //// +//// Nathan Yawn (nathan.yawn@opencores.org) //// +//// //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2010 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source 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 Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// This is a synchronization element between two clock domains. It +// uses toggle signaling - that is, clock domain 1 changes the state +// of TOGGLE_IN to indicate a change, rather than setting the level +// high. When TOGGLE_IN changes state, the output on D_OUT will be +// set to level '1', and will hold that value until D_RST is held +// high during a rising edge of DEST_CLK. D_OUT will be updated +// on the second rising edge of DEST_CLK after the state of +// TOGGLE_IN has changed. +// RESET is asynchronous. This is necessary to coordinate the reset +// between different clock domains with potentially different reset +// signals. +// +// Ports: +// DEST_CLK: Clock for the target clock domain +// D_SET: Synchronously set the output to '1' +// D_CLR: Synchronously reset the output to '0' +// RESET: Set all FF's to '0' (asynchronous) +// TOGGLE_IN: Toggle data signal from source clock domain +// D_OUT: Output to clock domain 2 + + +// Top module +module syncflop( + DEST_CLK, + D_SET, + D_RST, + RESETN, + TOGGLE_IN, + D_OUT + ); + + + input DEST_CLK; + input D_SET; + input D_RST; + input RESETN; + input TOGGLE_IN; + output D_OUT; + + reg sync1; + reg sync2; + reg syncprev; + reg srflop; + + wire syncxor; + wire srinput; + wire D_OUT; + + // Combinatorial assignments + assign syncxor = sync2 ^ syncprev; + assign srinput = syncxor | D_SET; + assign D_OUT = srflop | syncxor; + + // First DFF (always enabled) + always @ (posedge DEST_CLK or negedge RESETN) + begin + if(~RESETN) sync1 <= 1'b0; + else sync1 <= TOGGLE_IN; + end + + + // Second DFF (always enabled) + always @ (posedge DEST_CLK or negedge RESETN) + begin + if(~RESETN) sync2 <= 1'b0; + else sync2 <= sync1; + end + + + // Third DFF (always enabled, used to detect toggles) + always @ (posedge DEST_CLK or negedge RESETN) + begin + if(~RESETN) syncprev <= 1'b0; + else syncprev <= sync2; + end + + + // Set/Reset FF (holds detected toggles) + always @ (posedge DEST_CLK or negedge RESETN) + begin + if(~RESETN) srflop <= 1'b0; + else if(D_RST) srflop <= 1'b0; + else if (srinput) srflop <= 1'b1; + end + + +endmodule
diff --git a/verilog/rtl/ips/adv_dbg_if/rtl/syncreg.v b/verilog/rtl/ips/adv_dbg_if/rtl/syncreg.v new file mode 100644 index 0000000..ecc9764 --- /dev/null +++ b/verilog/rtl/ips/adv_dbg_if/rtl/syncreg.v
@@ -0,0 +1,158 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// syncreg.v //// +//// //// +//// //// +//// Synchronizes a register between two clock domains //// +//// //// +//// Author(s): //// +//// Nathan Yawn (nathan.yawn@opencores.org) //// +//// //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2010 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source 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 Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// This is a synchronization element between two clock domains. Domain A +// is considered the 'source' domain (produces the data), and Domain B +// is considered the 'destination' domain (consumes the data). It is assumed +// that clock A is faster than clock B, but this element will work +// regardless. The idea here is NOT to insure that domain B sees every +// change to the value generated by domain A. Rather, this device +// attempts to keep the value seen by domain B as current as possible, +// always updating to the latest value of the input in domain A. +// Thus, there may be dozens or hundreds of changes to register A +// which are not seen by domain B. There is no external acknowledge +// of receipt from domain B. Domain B simply wants the most current +// value of register A possible at any given time. +// Note the reset is asynchronous; this is necessary to coordinate between +// two clock domains which may have separate reset signals. I could find +// no other way to insure correct initialization with two separate +// reset signals. +// +// Ports: +// CLKA: Clock for the source domain +// CLKB: Clock for the destination domain +// RST: Asynchronously resets all sync elements, prepares +// unit for operation. +// DATA_IN: Data input from clock domain A +// DATA_OUT: Data output to clock domain B +// + + +// Top module +module syncreg ( + CLKA, + CLKB, + RSTN, + DATA_IN, + DATA_OUT + ); + + + input CLKA; + input CLKB; + input RSTN; + input [3:0] DATA_IN; + output [3:0] DATA_OUT; + + reg [3:0] regA; + reg [3:0] regB; + reg strobe_toggle; + reg ack_toggle; + + wire A_not_equal; + wire A_enable; + wire strobe_sff_out; + wire ack_sff_out; + wire [3:0] DATA_OUT; + + // Combinatorial assignments + assign A_enable = A_not_equal & ack_sff_out; + assign A_not_equal = !(DATA_IN == regA); + assign DATA_OUT = regB; + + // register A (latches input any time it changes) + always @ (posedge CLKA or negedge RSTN) + begin + if(~RSTN) + regA <= 4'b0; + else if(A_enable) + regA <= DATA_IN; + end + + + // register B (latches data from regA when enabled by the strobe SFF) + always @ (posedge CLKB or negedge RSTN) + begin + if(~RSTN) + regB <= 4'b0; + else if(strobe_sff_out) + regB <= regA; + end + + + // 'strobe' toggle FF + always @ (posedge CLKA or negedge RSTN) + begin + if(~RSTN) + strobe_toggle <= 1'b0; + else if(A_enable) + strobe_toggle <= ~strobe_toggle; + end + + + // 'ack' toggle FF + // This is set to '1' at reset, to initialize the unit. + always @ (posedge CLKB or negedge RSTN) + begin + if(~RSTN) + ack_toggle <= 1'b1; + else if (strobe_sff_out) + ack_toggle <= ~ack_toggle; + end + + // 'strobe' sync element + syncflop strobe_sff ( + .DEST_CLK (CLKB), + .D_SET (1'b0), + .D_RST (strobe_sff_out), + .RESETN (RSTN), + .TOGGLE_IN (strobe_toggle), + .D_OUT (strobe_sff_out) + ); + + // 'ack' sync element + syncflop ack_sff ( + .DEST_CLK (CLKA), + .D_SET (1'b0), + .D_RST (A_enable), + .RESETN (RSTN), + .TOGGLE_IN (ack_toggle), + .D_OUT (ack_sff_out) + ); +endmodule