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

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_uart/] [pronoc_jtag_uart.old] - Rev 48

Compare with Previous | Blame | View Log

/**************************************
* Module: pronoc_jtag_uart
* Date:2020-04-11  
* Author: alireza     
*
* Description: 
***************************************/
`define DONT_CHECK_SIM

// synthesis translate_off
`timescale 1ns / 1ps
// synthesis translate_on



module  pronoc_jtag_uart #(
    //wb parameter 
    parameter Aw           =   1,
    parameter SELw         =   4,
    parameter TAGw         =   3,
    parameter Dw           =   32,
    //uart parameter    
    parameter BUFF_Aw      =   6,//max is 16
    //uart simulator param 
    parameter SIM_BUFFER_SIZE=100,
    parameter SIM_WAIT_COUNT    =10000,
    //jtag parameter
    parameter JTAG_CONNECT= "XILINX_JTAG_WB",//"ALTERA_JTAG_WB" ,"XILINX_JTAG_WB"  
    parameter JTAG_INDEX= 126,
    parameter JDw = 32,
    parameter JAw=32,
    parameter JINDEXw=8,
    parameter JSTATUSw=8,
    parameter J2WBw = (JTAG_CONNECT== "XILINX_JTAG_WB") ? 1+1+JDw+JAw : 1,
    parameter WB2Jw= (JTAG_CONNECT== "XILINX_JTAG_WB") ? 1+JSTATUSw+JINDEXw+1+JDw  : 1

)(
 //wb
  clk,
  reset,
 // wb_irq,
  wb_dat_o,
  wb_ack_o,
  wb_adr_i,
  wb_stb_i,
  wb_cyc_i,
  wb_we_i,
  wb_dat_i,  
  
  //jtag 
  wb_to_jtag,
  jtag_to_wb
);
    
    //wb
    input            clk;
    input            reset;
  //  output           wb_irq;
    output  [ Dw-1: 0] wb_dat_o;
    output           wb_ack_o;
    input            wb_adr_i;
    input            wb_stb_i;
    input            wb_cyc_i;
    input            wb_we_i;
    input   [ Dw-1: 0] wb_dat_i;
   
  
    //jtag
    output [WB2Jw-1  : 0] wb_to_jtag;
    input  [J2WBw-1 : 0] jtag_to_wb; 
`ifndef DONT_CHECK_SIM
`ifdef MODEL_TECH 
    `define RUN_SIM
`endif
`ifdef VERILATOR
    `define RUN_SIM
`endif
`endif
    
`ifdef  RUN_SIM

    altera_simulator_UART #(
        .BUFFER_SIZE(SIM_BUFFER_SIZE),  
        .WAIT_COUNT(SIM_WAIT_COUNT)    
    )
    Suart
    (
        .reset(reset),
        .clk(clk),
        .s_dat_i(wb_dat_i),
        .s_sel_i(4'b1111),
        .s_addr_i(wb_adr_i),  
        .s_cti_i( ),
        .s_stb_i(wb_stb_i),
        .s_cyc_i(wb_cyc_i),
        .s_we_i(wb_we_i),    
        .s_dat_o(wb_dat_o),
        .s_ack_o(wb_ack_o),
        .RxD_din(8'd0),
        .RxD_wr(8'd0),
        .RxD_ready( )
    );


`else 
    pronoc_jtag_uart_hw #(
        .Aw(Aw),
        .SELw(SELw),
        .TAGw(TAGw),
        .Dw(Dw),
        .BUFF_Aw(BUFF_Aw),
        .JTAG_CONNECT(JTAG_CONNECT),
        .JTAG_INDEX(JTAG_INDEX),
        .JDw(JDw),
        .JAw(JAw),
        .JINDEXw(JINDEXw),
        .JSTATUSw(JSTATUSw),
        .J2WBw(J2WBw),
        .WB2Jw(WB2Jw)
    )
    uart_hw
    (
        .clk(clk),
        .reset(reset),
        .wb_dat_o(wb_dat_o),
        .wb_ack_o(wb_ack_o),
        .wb_adr_i(wb_adr_i),
        .wb_stb_i(wb_stb_i),
        .wb_cyc_i(wb_cyc_i),
        .wb_we_i(wb_we_i),
        .wb_dat_i(wb_dat_i),
        .wb_to_jtag(wb_to_jtag),
        .jtag_to_wb(jtag_to_wb)
    );

`endif


endmodule








module  pronoc_jtag_uart_hw #(
    //wb parameter 
    parameter Aw           =   1,
    parameter SELw         =   4,
    parameter TAGw         =   3,
    parameter Dw           =   32,
    //uart parameter    
    parameter BUFF_Aw      =   6,//max is 16
    //jtag parameter
    parameter JTAG_CONNECT= "XILINX_JTAG_WB",//"ALTERA_JTAG_WB" ,"XILINX_JTAG_WB"  
    parameter JTAG_INDEX= 126,
    parameter JDw = 32,
    parameter JAw=32,
    parameter JINDEXw=8,
    parameter JSTATUSw=8,
    parameter J2WBw = (JTAG_CONNECT== "XILINX_JTAG_WB") ? 1+1+JDw+JAw : 1,
    parameter WB2Jw= (JTAG_CONNECT== "XILINX_JTAG_WB") ? 1+JSTATUSw+JINDEXw+1+JDw  : 1

)(
 //wb
  clk,
  reset,
 // wb_irq,
  wb_dat_o,
  wb_ack_o,
  wb_adr_i,
  wb_stb_i,
  wb_cyc_i,
  wb_we_i,
  wb_dat_i,  
  
  //jtag 
  wb_to_jtag,
  jtag_to_wb
  

);

    function integer log2;
      input integer number; begin   
         log2=(number <=1) ? 1: 0;    
         while(2**log2<number) begin    
            log2=log2+1;    
         end       
      end   
    endfunction // log2 
    
    
     //wb interface
    localparam 
        DATA_REG = 1'b0,            
        CONTROL_REG  = 1'b1 ,  
        CONTROL_WSPACE_MSK = 32'hFFFF0000,
        DATA_RVALID_MSK = 32'h00008000,
        DATA_DATA_MSK = 32'h000000FF,
        B = 2 ** (BUFF_Aw-1),
        B_1 = B-1,
        Bw = log2(B),
        DEPTHw=log2(B+1);
       
        
    localparam  [Bw-1   :   0] Bint =   B_1[Bw-1    :   0];
    
    //wb
    input            clk;
    input            reset;
  //  output           wb_irq;
    output  reg[ Dw-1: 0] wb_dat_o;
    output    reg       wb_ack_o;
    input            wb_adr_i;
    input            wb_stb_i;
    input            wb_cyc_i;
    input            wb_we_i;
    input   [ Dw-1: 0] wb_dat_i;
   
  
    //jtag
    output [WB2Jw-1  : 0] wb_to_jtag;
    input  [J2WBw-1 : 0] jtag_to_wb; 




    //control reg 
    wire [31 : 0] ctrl_reg;
    reg  [15 : 0] wspace;    // The number of spaces available in the write FIFO.
    reg  [15 : 0] jtag_wspace;    // The number of spaces available in the jtag write FIFO.
     
    assign ctrl_reg [31 :16] = wspace;

    wire [7:0]  wb_to_fifo_dat,fifo_to_wb_dat,jtag_to_fifo_dat,fifo_to_jtag_dat;
    wire [BUFF_Aw-1: 0] wb_to_fifo_addr,jtag_to_fifo_addr;
  
      
    //wb_wr_jtag_rd
    reg [BUFF_Aw- 2      :   0] jtag_rd_ptr;
    reg [BUFF_Aw- 2      :   0] wb_wr_ptr;
    reg [BUFF_Aw -1      :   0] wb_to_jtag_depth;
    reg wb_to_fifo_we,fifo_to_wb_re;
    wire wb_fifo_full, wb_fifo_nearly_full, wb_fifo_empty;
    
    //jtag_wr_wb_rd
    reg [BUFF_Aw- 2      :   0] wb_rd_ptr;
    reg [BUFF_Aw- 2      :   0] jtag_wr_ptr;
    reg [BUFF_Aw -1      :   0] jtag_to_wb_depth;
    reg jtag_to_fifo_we,fifo_to_jtag_re;
    wire jtag_fifo_full, jtag_fifo_nearly_full, jtag_fifo_empty;

    
    
    wire [JSTATUSw-1 : 0] jtag_status_o;
    wire [JINDEXw-1 : 0] jtag_index_o;
    wire jtag_stb_i,jtag_we_i;
    wire [JDw-1 : 0] jtag_dat_i;
    wire [JDw-1 : 0] jtag_dat_o;
    wire [JAw-1 : 0] jtag_addr_i;    
    reg jtag_ack_o; 
    reg jtag_rdat_valid,wb_rdat_valid;
 
   
    reg wb_ack_o_next,jtag_ack_o_next;


    always @ (*) begin
        wb_ack_o_next =1'b0;
        wb_to_fifo_we =1'b0;
        fifo_to_jtag_re=1'b0;
        wb_dat_o[7:0]=fifo_to_wb_dat;
        wb_dat_o[15] = wb_rdat_valid;
        if(wb_stb_i & wb_we_i ) begin 
                case(wb_adr_i)
                DATA_REG:begin
                    if(~wb_fifo_full)begin 
                        wb_to_fifo_we=1'b1;
                        wb_ack_o_next =1'b1;
                    end                
                end
                CONTROL_REG:begin                
                    // set the bits of control reg. //TODO add intrrupt control registers
                    wb_ack_o_next =1'b1;
                end
                endcase
        end //sa_stb_i && sa_we_i
        if(wb_stb_i & ~wb_we_i ) begin 
                case(wb_adr_i)
                DATA_REG:begin
                    wb_dat_o[7:0]=fifo_to_wb_dat;
                    wb_dat_o[15] = wb_rdat_valid;
                    wb_ack_o_next =1'b1;
                    if(~jtag_fifo_empty)begin
                        fifo_to_jtag_re=1'b1;                                            
                    end                
                end
                CONTROL_REG:begin                
                    // read control reg
                     wb_dat_o = ctrl_reg;
                     wb_ack_o_next =1'b1;
                end
                endcase
        end
    end//always
    
    reg jtag_to_fifo_we_next;
  
    reg stb1,stb2;
    wire jtag_stb_valid = stb1 & ~stb2;// fix jtag clock diffrence
  
    always @(*) begin
        jtag_to_fifo_we_next=1'b0;
        jtag_ack_o_next =1'b0;
        fifo_to_wb_re=1'b0;
        if(jtag_stb_valid) begin 
            if(~wb_fifo_empty) fifo_to_wb_re=1'b1;//make one cycle delay for wr enable
             jtag_ack_o_next =1'b1;       
            if( ~jtag_fifo_full && jtag_to_fifo_dat[7:0]!=0) jtag_to_fifo_we_next=1'b1;
        end 
        
    end
    
   
   
    always @ (posedge clk or posedge reset)begin
        if (reset) begin 
            wb_ack_o<=1'b0;
            jtag_ack_o<=1'b0;
            jtag_to_fifo_we<=1'b0;
            stb1<=1'b0;
            stb2<=1'b0;
            jtag_rdat_valid<=1'b0;
        end else begin
            wb_ack_o<= wb_ack_o_next;
            jtag_ack_o<=jtag_ack_o_next;
            jtag_to_fifo_we<=jtag_to_fifo_we_next;
            stb1<=jtag_stb_i;
            stb2<=stb1;
            
            if(~wb_fifo_empty) jtag_rdat_valid<=1'b1;
            else if(jtag_ack_o ) jtag_rdat_valid<=1'b0;
            
            if(~jtag_fifo_empty) wb_rdat_valid<=1'b1;
            else if(wb_ack_o ) wb_rdat_valid<=1'b0;           
            
        end
    end
    
   
    
    assign wb_to_fifo_dat = wb_dat_i [7:0];

    uart_dual_port_ram #(
        .Dw(8),
        .Aw(BUFF_Aw)
    )
    uart_ram
    (
        //wb_to_jtag
        .data_a(wb_to_fifo_dat),        
        .addr_a(wb_to_fifo_addr),
        .we_a  (wb_to_fifo_we),
        .q_a   (fifo_to_wb_dat),
        
        //jtag_to_wb
        .data_b(jtag_to_fifo_dat),
        .addr_b(jtag_to_fifo_addr),     
        .we_b  (jtag_to_fifo_we),
        .q_b   (fifo_to_jtag_dat),
        
        .clk   (clk)            
    );

   
   generate  
   if(JTAG_CONNECT == "XILINX_JTAG_WB")begin: xilinx_jwb 
        assign wb_to_jtag = {jtag_status_o,jtag_ack_o,jtag_dat_o,jtag_index_o,clk};
        assign {jtag_addr_i,jtag_stb_i,jtag_we_i,jtag_dat_i} = jtag_to_wb;
   end else  if(JTAG_CONNECT == "AlTERA_JTAG_WB")begin: altera_jwb 
   
        vjtag_wb #(
            .VJTAG_INDEX(JTAG_INDEX),
            .DW(JDw),
            .AW(JAw),
            .SW(JSTATUSw),
        
            //wishbone port parameters
            .M_Aw(Aw),
            .TAGw(TAGw)
        )
        vjtag_inst
        (
            .clk(clk),
            .reset(reset),  
            .status_i(jtag_status_o), 
             //wishbone master interface signals
            .m_sel_o(),
            .m_dat_o(jtag_dat_i),
            .m_addr_o(jtag_addr_i),
            .m_cti_o(),
            .m_stb_o(jtag_stb_i),
            .m_cyc_o(),
            .m_we_o(jtag_we_i),
            .m_dat_i(jtag_dat_o),
            .m_ack_i(jtag_ack_o)     
        
        );
   
   
        assign wb_to_jtag[0] = clk;
   end
   endgenerate 
    
    assign wb_to_fifo_addr = (wb_to_fifo_we) ? {1'b0,wb_wr_ptr} : {1'b1,wb_rd_ptr};
    assign jtag_to_fifo_addr = (jtag_to_fifo_we) ? {1'b1,jtag_wr_ptr} : {1'b0,jtag_rd_ptr};
    assign jtag_status_o=0;
    assign jtag_index_o = JTAG_INDEX; 
    assign jtag_to_fifo_dat = jtag_dat_i[7:0]; 
    reg [7:0] jtag_rd_dat;
    always @(posedge clk)begin 
        if(reset)begin 
            jtag_rd_dat<=8'd0;
        end else if(fifo_to_wb_re & ~jtag_to_fifo_we)begin 
            jtag_rd_dat<=fifo_to_jtag_dat;
        end
    end    
    assign jtag_dat_o[23 : 0] = (jtag_rdat_valid)? {jtag_wspace,jtag_rd_dat} : {jtag_wspace,8'd0};

 
 
 
    /*************
     * FIFO pointers
     * ***********/

    //pointers update wb_wr_jtag_rd
    always @(posedge clk)
    begin
       if (reset) begin
          jtag_rd_ptr <= {Bw{1'b0}};
          wb_wr_ptr <= 0;
          wb_to_jtag_depth  <= {DEPTHw{1'b0}};
       end
       else begin
          if (wb_to_fifo_we) wb_wr_ptr <= (wb_wr_ptr==Bint)?   {Bw{1'b0}} : wb_wr_ptr + 1'b1;
          if (fifo_to_wb_re ) jtag_rd_ptr <= (jtag_rd_ptr==Bint)?   {Bw{1'b0}} : jtag_rd_ptr + 1'b1;
          if (wb_to_fifo_we & ~(fifo_to_wb_re )) wb_to_jtag_depth <=  wb_to_jtag_depth + 1'b1;
          else if (~wb_to_fifo_we & ( fifo_to_wb_re)) wb_to_jtag_depth <=    wb_to_jtag_depth - 1'b1;
       end
    end
    
    assign wb_fifo_full = wb_to_jtag_depth == B;
    assign wb_fifo_nearly_full = wb_to_jtag_depth >= B-1;
    assign wb_fifo_empty = wb_to_jtag_depth == {DEPTHw{1'b0}};
   
    
   
    
    //pointers update wb_rd_jtag_wr
    always @(posedge clk)
    begin
       if (reset) begin
          wb_rd_ptr <= {Bw{1'b0}};
          jtag_wr_ptr <= 0;
          jtag_to_wb_depth  <= {DEPTHw{1'b0}};
       end
       else begin
          if (jtag_to_fifo_we ) jtag_wr_ptr <= (jtag_wr_ptr==Bint)?   {Bw{1'b0}} : jtag_wr_ptr + 1'b1;
          if (fifo_to_jtag_re) wb_rd_ptr <= (wb_rd_ptr==Bint)?   {Bw{1'b0}} : wb_rd_ptr + 1'b1;
          if (jtag_to_fifo_we  & ~fifo_to_jtag_re) jtag_to_wb_depth <=  jtag_to_wb_depth + 1'b1;
          else if (~(jtag_to_fifo_we ) & fifo_to_jtag_re) jtag_to_wb_depth <=    jtag_to_wb_depth - 1'b1;
       end
    end
    
    assign jtag_fifo_full = jtag_to_wb_depth == B;
    assign jtag_fifo_nearly_full = jtag_to_wb_depth >= B-1;
    assign jtag_fifo_empty = jtag_to_wb_depth == {DEPTHw{1'b0}};


    wire  [BUFF_Aw -1      :   0] remain = B- wb_to_jtag_depth; 
    wire  [BUFF_Aw -1      :   0] jtag_remain = B- jtag_to_wb_depth; 
    always @(*)begin 
        wspace = 16'd0;
        jtag_wspace=16'd0;
        wspace[BUFF_Aw-1 : 0] = remain;
        jtag_wspace[BUFF_Aw-1 : 0] = jtag_remain;
    end    


endmodule




// Quartus II Verilog Template
// True Dual Port RAM with single clock


module uart_dual_port_ram
#(
    parameter Dw=8, 
    parameter Aw=6   
)
(
   data_a,
   data_b,
   addr_a,
   addr_b,
   we_a,
   we_b,
   clk,
   q_a,
   q_b
);


    input [(Dw-1):0] data_a, data_b;
    input [(Aw-1):0] addr_a, addr_b;
    input we_a, we_b, clk;
    output  reg [(Dw-1):0] q_a, q_b;

    // Declare the RAM variable
    reg [Dw-1:0] ram[2**Aw-1:0];

       // Port A 
    always @ (posedge clk)
    begin
        if (we_a) 
        begin
            ram[addr_a] <= data_a;
            q_a <= data_a;
        end
        else 
        begin
            q_a <= ram[addr_a];
        end 
    end 

    // Port B 
    always @ (posedge clk)
    begin
        if (we_b) 
        begin
            ram[addr_b] <= data_b;
            q_b <= data_b;
        end
        else 
        begin
            q_b <= ram[addr_b];
        end 
    end
    
    // synthesis translate_off


    integer i;
    initial begin 
       for (i=0; i<(2**Aw);i=i+1 ) ram[i] ="*";
    end
// synthesis translate_on
 
   
endmodule







Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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