OpenCores
URL https://opencores.org/ocsvn/an-fpga-implementation-of-low-latency-noc-based-mpsoc/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk
/********************************************************************** ** File: xilinx_jtag_wb.v ** ** ** Copyright (C) 2020 Alireza Monemi ** ** This file is part of ProNoC ** ** ProNoC ( stands for Prototype Network-on-chip) 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 of the License, or (at your option) any later version. ** ** ProNoC 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 ProNoC. If not, see . ** ** ** Description: ** xilinx bscan chain to wishbon bus interface. It prvide simple read/write on ** whishbone bus. Does not support burst transaction. ** *******************************************************************/ // synthesis translate_off `timescale 1ns / 1ps // synthesis translate_on module xilinx_jtag_wb #( parameter JTAG_CHAIN=4, // Only used for Virtex 4/5 devices. May be 1, 2, 3, or 4 parameter JWB_NUM=1, parameter JDw=32, parameter JAw=32, parameter JINDEXw=8, parameter JSTATUSw=8, parameter CTRL_REG_INDEX =127 )( // clk, get the clock from wb interface reset, cpu_en, system_reset, wb_to_jtag_all, jtag_to_wb_all ); function integer log2; input integer number; begin log2=(number <=1) ? 1: 0; while(2**log21)? log2(JWB_NUM):1; wire [BIN_WIDTH-1 : 0] jtag_sel_bin; jtag_one_hot_to_bin #( .ONE_HOT_WIDTH(JWB_NUM), .BIN_WIDTH(BIN_WIDTH) ) convert ( .one_hot_code(jtag_sel_onehot), .bin_code(jtag_sel_bin) ); assign wb_to_jtag_status=wb_to_jtag_status_all[jtag_sel_bin]; assign wb_to_jtag_ack =wb_to_jtag_ack_all_latched[jtag_sel_bin]; // assign wb_to_jtag_dat=wb_to_jtag_dat_all [jtag_sel_bin]; //use one-hot mux if index doesnt match the read data is zero jtag_one_hot_mux #( .IN_WIDTH(JDw*JWB_NUM), .SEL_WIDTH(JWB_NUM), .OUT_WIDTH(JDw) ) one_hot_mux ( .mux_in(wb_to_jtag_dat_all_latched), .mux_out(wb_to_jtag_dat), .sel(jtag_sel_onehot_reg) ); //assign {wb_to_jtag_status,wb_to_jtag_ack,wb_to_jtag_dat} wire mem_ctrl_jtag_ack; xilinx_jtag_mem_ctrl #( .JTAG_CHAIN(JTAG_CHAIN), .Dw(JDw), .Aw(JAw), .INDEXw(JINDEXw) ) mem_ctrl ( // .ps(), // .clk(clk), .tclk (tclk ), .wb_to_jtag_status(wb_to_jtag_status ), .wb_to_jtag_dat (wb_to_jtag_dat ), .wb_to_jtag_ack (mem_ctrl_jtag_ack ), .jtag_to_wb_ir ( ), .jtag_to_wb_index (jtag_to_wb_index ), .jtag_to_wb_dat (jtag_to_wb_dat ), .jtag_to_wb_addr (jtag_to_wb_addr ), .jtag_to_wb_stb (jtag_to_wb_stb ), .jtag_to_wb_we (jtag_to_wb_we ), .reset (reset) ); reg rst_ctrl_ack; `ifdef SYNC_RESET_MODE always @ (posedge tclk )begin `else always @ (posedge tclk or posedge reset)begin `endif if(reset) begin ctrl_reg <=2'b00; end else if(jtag_to_wb_index == CTRL_REG_INDEX)begin if(jtag_to_wb_we & jtag_to_wb_stb) begin ctrl_reg <= jtag_to_wb_dat[1:0]; end end end `ifdef SYNC_RESET_MODE always @ (posedge tclk )begin `else always @ (posedge tclk or posedge reset)begin `endif if(reset) begin rst_ctrl_ack<=1'b0; end else begin rst_ctrl_ack <= jtag_to_wb_stb; end end assign mem_ctrl_jtag_ack = ((jtag_to_wb_index == CTRL_REG_INDEX) || jtag_sel_onehot == {JWB_NUM{1'b0}} ) ? rst_ctrl_ack : wb_to_jtag_ack; endmodule module wb_to_jtag_latch ( clk, jtag_clk, in, out ); input clk,jtag_clk,in; output out; reg out_latch,reset_out; always @ (posedge clk) begin if(in) out_latch<=1'b1; else if(reset_out) out_latch<=1'b0; end always @(posedge jtag_clk)begin if(out_latch | in) reset_out<=1'b1; else reset_out<=1'b0; end assign out = reset_out ; endmodule /************** * xilinx_jtag_mem_ctrl * ************/ module xilinx_jtag_mem_ctrl #( parameter JTAG_CHAIN=4, parameter Dw=32, parameter Aw=32, parameter INDEXw=8, parameter STATUSw=8 )( // ps, wb_to_jtag_status, wb_to_jtag_dat, wb_to_jtag_ack, jtag_to_wb_ir, jtag_to_wb_index, jtag_to_wb_dat, jtag_to_wb_addr, jtag_to_wb_stb, jtag_to_wb_we, // clk, reset, tclk ); localparam Iw=3; input [STATUSw-1 : 0] wb_to_jtag_status; input [Dw-1 : 0] wb_to_jtag_dat; input wb_to_jtag_ack; output [INDEXw-1 : 0] jtag_to_wb_index; output [Iw-1 : 0] jtag_to_wb_ir; output [Dw-1 : 0] jtag_to_wb_dat; output [Aw-1 : 0] jtag_to_wb_addr; output jtag_to_wb_stb; output jtag_to_wb_we; //input clk; input reset; output tclk; localparam STATE_NUM=3, IDEAL =1, WB_WR_DATA=2, WB_RD_DATA=4; reg [STATE_NUM-1 : 0] ns, ps; wire reset_ps=1'b0; wire wb_wr_addr_en, wb_wr_data_en, wb_rd_data_en; reg wr_mem_en, rd_mem_en;// wb_cap_rd; reg [Aw-1 : 0] wb_addr,wb_addr_next; // reg [Dw-1 : 0] wb_rd_data; wire [Dw-1 : 0] wb_wr_data; reg wb_addr_inc; assign jtag_to_wb_stb = (wr_mem_en | rd_mem_en) & ~reset_ps; assign jtag_to_wb_we = wr_mem_en; assign jtag_to_wb_dat = wb_wr_data; assign jtag_to_wb_addr = wb_addr; localparam JDw= (Dw > Aw)? Dw : Aw; wire [JDw-1 :0] data_out; wire [JDw-1 :0] data_in; //assign data_in = wb_rd_data; assign data_in = wb_to_jtag_dat; wire ir_updated; xilinx_jtag_ctrl #( .JTAG_CHAIN(JTAG_CHAIN), .Dw(JDw), .INDEXw(INDEXw), .STw(STATUSw) ) vjtag_ctrl_inst ( // .clk(clk), .ir(jtag_to_wb_ir ), .status_i(wb_to_jtag_status), .index(jtag_to_wb_index), .tck(tclk), .reset(reset), .data_out(data_out), .data_in(data_in), .wb_wr_addr_en(wb_wr_addr_en), .wb_wr_data_en(wb_wr_data_en), .wb_rd_data_en(wb_rd_data_en), .ir_updated(ir_updated) ); `ifdef SYNC_RESET_MODE always @ (posedge tclk )begin `else always @ (posedge tclk or posedge reset)begin `endif if(reset) begin wb_addr <= {Aw{1'b0}}; // wb_wr_data <= {Dw{1'b0}}; // wb_rd_data <= {Dw{1'b0}}; ps <= IDEAL; end else begin wb_addr <= wb_addr_next; if(reset_ps) ps <= IDEAL; else ps <= ns; // if(wb_wr_data_en) wb_wr_data <= data_out; // if(wb_cap_rd | ir_updated ) wb_rd_data <= wb_to_jtag_dat; end end assign wb_wr_data = data_out; always @(*)begin wb_addr_next= wb_addr; if(wb_wr_addr_en) wb_addr_next = data_out [Aw-1 : 0]; else if (wb_addr_inc) wb_addr_next = wb_addr +1'b1; end always @(*)begin ns=ps; wr_mem_en =1'b0; rd_mem_en =1'b0; wb_addr_inc=1'b0; // wb_cap_rd=1'b0; case(ps) IDEAL : begin if(wb_wr_data_en) ns= WB_WR_DATA; if(wb_rd_data_en) begin ns= WB_RD_DATA; // wb_cap_rd=1'b1; end end WB_WR_DATA: begin wr_mem_en =1'b1; if(wb_to_jtag_ack) begin wr_mem_en =1'b0; ns=IDEAL; wb_addr_inc=1'b1; end end WB_RD_DATA: begin rd_mem_en =1'b1; //wb_cap_rd=1'b1; if(wb_to_jtag_ack) begin rd_mem_en =1'b0; // wb_cap_rd=1'b0; ns=IDEAL; //wb_addr_inc=1'b1; end end default begin ns=IDEAL; end endcase end endmodule /**************** * xilinx_jtag_ctrl * *************/ module xilinx_jtag_ctrl #( parameter JTAG_CHAIN=4, parameter Dw=32, parameter INDEXw=8, parameter STw=8 )( // clk, tck, reset, ir_updated, status_i, data_out, data_in, wb_wr_addr_en, wb_wr_data_en, wb_rd_data_en, ir, index ); localparam Iw=3, M1 = (Dw>Iw)? Dw :Iw, M2 = (M1>INDEXw)? M1 :INDEXw, BUFFw= M1+4; // IR states localparam [Iw-1:0] UPDATE_WB_ADDR = 3'b111, UPDATE_WB_WR_DATA = 3'b110, UPDATE_WB_RD_DATA = 3'b101, RD_STATUS =3'b100, UPDATE_CTRL =3'b001, BYPASS = 3'b000;//not used //IO declaration // input clk; input reset; output tck; input [STw-1 :0] status_i; input [Dw-1 :0] data_in; output reg wb_wr_addr_en, wb_wr_data_en, wb_rd_data_en; output reg [Iw-1:0] ir; output reg [INDEXw-1:0] index; output reg [Dw-1 :0] data_out; output reg ir_updated; wire tdo, tck, tdi; wire cdr ,sdr,udr; wire tlr; xilinx_jtag_bscan #( .JTAG_CHAIN(JTAG_CHAIN) ) vjtag_inst ( .tdo ( tdo ), .tck ( tck ), .tdi ( tdi ), .tlr ( tlr ), .cdr ( cdr ), .sdr ( sdr ), .udr ( udr ) ); // internal registers (* KEEP = "TRUE" *) reg [BUFFw-1 : 0] jtag_shift_buffer,jtag_shift_buffer_next; assign tdo = jtag_shift_buffer[0]; always @ (*)begin jtag_shift_buffer_next=jtag_shift_buffer; if( sdr ) jtag_shift_buffer_next={tdi,jtag_shift_buffer[BUFFw-1:1]};// shift buffer else if( cdr )begin case(ir) RD_STATUS:begin jtag_shift_buffer_next[STw-1 : 0] = status_i; end UPDATE_WB_RD_DATA: begin jtag_shift_buffer_next[Dw-1 : 0] = data_in; //synthesis translate_off if(data_in[7:0]!=7'd0 && index==126) $write("%c",data_in[7:0]); //synthesis translate_on end default :begin jtag_shift_buffer_next=jtag_shift_buffer; end endcase end end localparam UPDATE_INDEX =0, UPDATE_IR=1, UPDATE_DAT=2; wire update_index_flag = jtag_shift_buffer[M1+UPDATE_INDEX]; wire update_ir_flag = jtag_shift_buffer[M1+UPDATE_IR]; wire update_dat_flag = jtag_shift_buffer[M1+UPDATE_DAT]; always @(posedge tck ) begin jtag_shift_buffer<=jtag_shift_buffer_next; end reg mask; always @(posedge tck ) begin if( udr)begin if(update_index_flag) begin index <= jtag_shift_buffer[INDEXw-1 : 0]; ir<={Iw{1'b0}}; mask<=1'b1; end else if(update_ir_flag )begin ir <= jtag_shift_buffer[Iw-1 : 0]; mask<=1'b1; end if(update_dat_flag )begin data_out <= jtag_shift_buffer[Dw-1 : 0]; mask<=1'b0; end end end always @( posedge tck ) begin if( udr && update_ir_flag ) ir_updated<=1'b1; else ir_updated<=1'b0; end // assign data_out = jtag_shift_buffer[Dw-1 : 0]; /* always @(posedge tck ) begin if( sdr ) jtag_shift_buffer<={tdi,jtag_shift_buffer[BUFFw-1:1]};// shift buffer if( cdr ) jtag_shift_buffer<={data_in,ir}; if( udr ) ir <= jtag_shift_buffer_next[Iw-1:0]; end */ //always @(posedge tck or posedge reset) always @(posedge tck) begin //if( reset ) begin // wb_wr_addr1<=1'b0; // wb_wr_data1<=1'b0; //end else begin wb_wr_addr_en<=(ir== UPDATE_WB_ADDR || ir== UPDATE_WB_RD_DATA) & udr & update_dat_flag; wb_wr_data_en<=((ir== UPDATE_WB_WR_DATA|| ir==UPDATE_CTRL) & udr & update_dat_flag); wb_rd_data_en<=((ir== UPDATE_WB_RD_DATA) & cdr & ~mask); //end end endmodule /************** * xilinx_jtag_bscan * ************/ module xilinx_jtag_bscan #( // Only used for Virtex 4/5 devices parameter JTAG_CHAIN = 4 // May be 1, 2, 3, or 4 ) ( tck, tdo, tdi, tlr, sdr, cdr, udr ); input tdo; output tck; output tdi; output tlr; output sdr; output cdr; output udr; wire tck_i; wire sel; wire shift,update,capture; assign sdr = shift & sel; assign udr = update & sel; assign cdr = capture & sel; `ifdef MODEL_TECH `define RUN_SIM `endif `ifdef VERILATOR `define RUN_SIM `endif `ifdef RUN_SIM BSCANE2_sim #( .JTAG_CHAIN(JTAG_CHAIN) // Value for USER command. ) bse2_inst ( .CAPTURE(capture), // 1-bit output: CAPTURE output from TAP controller. .DRCK(), // 1-bit output: Gated TCK output. When SEL is asserted, DRCK toggles when CAPTURE or SHIFT are asserted. .RESET(tlr), // 1-bit output: Reset output for TAP controller. .RUNTEST(), // 1-bit output: Output asserted when TAP controller is in Run Test/Idle state. .SEL(sel), // 1-bit output: USER instruction active output. .SHIFT(shift), // 1-bit output: SHIFT output from TAP controller. .TCK(tck), // 1-bit output: Test Clock output. Fabric connection to TAP Clock pin. .TDI(tdi), // 1-bit output: Test Data Input (TDI) output from TAP controller. .TMS( ), // 1-bit output: Test Mode Select output. Fabric connection to TAP. .UPDATE(update), // 1-bit output: UPDATE output from TAP controller .TDO(tdo) // 1-bit input: Test Data Output (TDO) input for USER function. ); `else BSCANE2 #( .JTAG_CHAIN(JTAG_CHAIN) // Value for USER command. ) bse2_inst ( .CAPTURE(capture), // 1-bit output: CAPTURE output from TAP controller. .DRCK( ), // 1-bit output: Gated TCK output. When SEL is asserted, DRCK toggles when CAPTURE or SHIFT are asserted. .RESET(tlr), // 1-bit output: Reset output for TAP controller. .RUNTEST(), // 1-bit output: Output asserted when TAP controller is in Run Test/Idle state. .SEL(sel), // 1-bit output: USER instruction active output. .SHIFT(shift), // 1-bit output: SHIFT output from TAP controller. .TCK(tck), // 1-bit output: Test Clock output. Fabric connection to TAP Clock pin. .TDI(tdi), // 1-bit output: Test Data Input (TDI) output from TAP controller. .TMS( ), // 1-bit output: Test Mode Select output. Fabric connection to TAP. .UPDATE(update), // 1-bit output: UPDATE output from TAP controller .TDO(tdo) // 1-bit input: Test Data Output (TDO) input for USER function. ); // BUFG clk_buf(tck, tck_i); `endif endmodule module jtag_one_hot_to_bin #( parameter ONE_HOT_WIDTH = 4, parameter BIN_WIDTH = (ONE_HOT_WIDTH>1)? log2(ONE_HOT_WIDTH):1 ) ( input [ONE_HOT_WIDTH-1 : 0] one_hot_code, output [BIN_WIDTH-1 : 0] bin_code ); function integer log2; input integer number; begin log2=(number <=1) ? 1: 0; while(2**log21)begin :if1 for(i=0; i

Subversion Repositories an-fpga-implementation-of-low-latency-noc-based-mpsoc

[/] [an-fpga-implementation-of-low-latency-noc-based-mpsoc/] [trunk/] [mpsoc/] [rtl/] [src_peripheral/] [jtag/] [jtag_wb/] [xilinx_jtag_wb.v] - Blame information for rev 48

Details | Compare with Previous | View Log

Line No. Rev Author Line

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.