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