module vjtag_wb #(
|
module vjtag_wb #(
|
parameter VJTAG_INDEX=126,
|
parameter VJTAG_INDEX=126,
|
parameter DW=32,
|
parameter DW=32,
|
parameter AW=32,
|
parameter AW=32,
|
parameter SW=32,
|
parameter SW=32,
|
|
|
//wishbone port parameters
|
//wishbone port parameters
|
parameter S_Aw = 7,
|
parameter S_Aw = 7,
|
parameter M_Aw = 32,
|
parameter M_Aw = 32,
|
parameter TAGw = 3,
|
parameter TAGw = 3,
|
parameter SELw = 4
|
parameter SELw = 4
|
|
|
|
|
)(
|
)(
|
clk,
|
clk,
|
reset,
|
reset,
|
status_i,
|
status_i,
|
|
|
//wishbone master interface signals
|
//wishbone master interface signals
|
m_sel_o,
|
m_sel_o,
|
m_dat_o,
|
m_dat_o,
|
m_addr_o,
|
m_addr_o,
|
m_cti_o,
|
m_cti_o,
|
m_stb_o,
|
m_stb_o,
|
m_cyc_o,
|
m_cyc_o,
|
m_we_o,
|
m_we_o,
|
m_dat_i,
|
m_dat_i,
|
m_ack_i
|
m_ack_i
|
|
|
);
|
);
|
|
|
//IO declaration
|
//IO declaration
|
input reset,clk;
|
input reset,clk;
|
input [SW-1 : 0] status_i;
|
input [SW-1 : 0] status_i;
|
|
|
//wishbone master interface signals
|
//wishbone master interface signals
|
output [SELw-1 : 0] m_sel_o;
|
output [SELw-1 : 0] m_sel_o;
|
output [DW-1 : 0] m_dat_o;
|
output [DW-1 : 0] m_dat_o;
|
output [M_Aw-1 : 0] m_addr_o;
|
output [M_Aw-1 : 0] m_addr_o;
|
output [TAGw-1 : 0] m_cti_o;
|
output [TAGw-1 : 0] m_cti_o;
|
output m_stb_o;
|
output m_stb_o;
|
output m_cyc_o;
|
output m_cyc_o;
|
output m_we_o;
|
output m_we_o;
|
input [DW-1 : 0] m_dat_i;
|
input [DW-1 : 0] m_dat_i;
|
input m_ack_i;
|
input m_ack_i;
|
|
|
|
|
localparam STATE_NUM=3,
|
localparam STATE_NUM=3,
|
IDEAL =1,
|
IDEAL =1,
|
WB_WR_DATA=2,
|
WB_WR_DATA=2,
|
WB_RD_DATA=4;
|
WB_RD_DATA=4;
|
|
|
reg [STATE_NUM-1 : 0] ps,ns;
|
reg [STATE_NUM-1 : 0] ps,ns;
|
|
|
wire [DW-1 :0] data_out, data_in;
|
wire [DW-1 :0] data_out, data_in;
|
wire wb_wr_addr_en, wb_wr_data_en, wb_rd_data_en;
|
wire wb_wr_addr_en, wb_wr_data_en, wb_rd_data_en;
|
reg wr_mem_en, rd_mem_en, wb_cap_rd;
|
reg wr_mem_en, rd_mem_en, wb_cap_rd;
|
|
|
reg [AW-1 : 0] wb_addr,wb_addr_next;
|
reg [AW-1 : 0] wb_addr,wb_addr_next;
|
reg [DW-1 : 0] wb_wr_data,wb_rd_data;
|
reg [DW-1 : 0] wb_wr_data,wb_rd_data;
|
reg wb_addr_inc;
|
reg wb_addr_inc;
|
|
|
|
|
assign m_cti_o = 3'b000;
|
assign m_cti_o = 3'b000;
|
assign m_sel_o = 4'b1111;
|
assign m_sel_o = 4'b1111;
|
assign m_cyc_o = m_stb_o;
|
assign m_cyc_o = m_stb_o;
|
assign m_stb_o = wr_mem_en | rd_mem_en;
|
assign m_stb_o = wr_mem_en | rd_mem_en;
|
assign m_we_o = wr_mem_en;
|
assign m_we_o = wr_mem_en;
|
assign m_dat_o = wb_wr_data;
|
assign m_dat_o = wb_wr_data;
|
assign m_addr_o = wb_addr;
|
assign m_addr_o = wb_addr;
|
assign data_in = wb_rd_data;
|
assign data_in = wb_rd_data;
|
//vjtag vjtag signals declaration
|
//vjtag vjtag signals declaration
|
|
|
|
|
localparam VJ_DW= (DW > AW)? DW : AW;
|
localparam VJ_DW= (DW > AW)? DW : AW;
|
|
|
|
|
vjtag_ctrl #(
|
vjtag_ctrl #(
|
.DW(VJ_DW),
|
.DW(VJ_DW),
|
.VJTAG_INDEX(VJTAG_INDEX),
|
.VJTAG_INDEX(VJTAG_INDEX),
|
.STW(SW)
|
.STW(SW)
|
)
|
)
|
vjtag_ctrl_inst
|
vjtag_ctrl_inst
|
(
|
(
|
.clk(clk),
|
.clk(clk),
|
.reset(reset),
|
.reset(reset),
|
.data_out(data_out),
|
.data_out(data_out),
|
.data_in(data_in),
|
.data_in(data_in),
|
.wb_wr_addr_en(wb_wr_addr_en),
|
.wb_wr_addr_en(wb_wr_addr_en),
|
.wb_wr_data_en(wb_wr_data_en),
|
.wb_wr_data_en(wb_wr_data_en),
|
.wb_rd_data_en(wb_rd_data_en),
|
.wb_rd_data_en(wb_rd_data_en),
|
.status_i(status_i)
|
.status_i(status_i)
|
);
|
);
|
|
|
|
|
|
`ifdef SYNC_RESET_MODE
|
|
always @ (posedge clk )begin
|
|
`else
|
always @(posedge clk or posedge reset) begin
|
always @(posedge clk or posedge reset) begin
|
|
`endif
|
|
|
if(reset) begin
|
if(reset) begin
|
wb_addr <= {AW{1'b0}};
|
wb_addr <= {AW{1'b0}};
|
wb_wr_data <= {DW{1'b0}};
|
wb_wr_data <= {DW{1'b0}};
|
ps <= IDEAL;
|
ps <= IDEAL;
|
end else begin
|
end else begin
|
wb_addr <= wb_addr_next;
|
wb_addr <= wb_addr_next;
|
ps <= ns;
|
ps <= ns;
|
if(wb_wr_data_en) wb_wr_data <= data_out;
|
if(wb_wr_data_en) wb_wr_data <= data_out;
|
if(wb_cap_rd) wb_rd_data <= m_dat_i;
|
if(wb_cap_rd) wb_rd_data <= m_dat_i;
|
end
|
end
|
end
|
end
|
|
|
|
|
always @(*)begin
|
always @(*)begin
|
wb_addr_next= wb_addr;
|
wb_addr_next= wb_addr;
|
if(wb_wr_addr_en) wb_addr_next = data_out [AW-1 : 0];
|
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;
|
else if (wb_addr_inc) wb_addr_next = wb_addr +1'b1;
|
end
|
end
|
|
|
|
|
|
|
always @(*)begin
|
always @(*)begin
|
ns=ps;
|
ns=ps;
|
wr_mem_en =1'b0;
|
wr_mem_en =1'b0;
|
rd_mem_en =1'b0;
|
rd_mem_en =1'b0;
|
wb_addr_inc=1'b0;
|
wb_addr_inc=1'b0;
|
wb_cap_rd=1'b0;
|
wb_cap_rd=1'b0;
|
case(ps)
|
case(ps)
|
IDEAL : begin
|
IDEAL : begin
|
if(wb_wr_data_en) ns= WB_WR_DATA;
|
if(wb_wr_data_en) ns= WB_WR_DATA;
|
if(wb_rd_data_en) ns= WB_RD_DATA;
|
if(wb_rd_data_en) ns= WB_RD_DATA;
|
end
|
end
|
WB_WR_DATA: begin
|
WB_WR_DATA: begin
|
wr_mem_en =1'b1;
|
wr_mem_en =1'b1;
|
if(m_ack_i) begin
|
if(m_ack_i) begin
|
ns=IDEAL;
|
ns=IDEAL;
|
wb_addr_inc=1'b1;
|
wb_addr_inc=1'b1;
|
end
|
end
|
end
|
end
|
WB_RD_DATA: begin
|
WB_RD_DATA: begin
|
rd_mem_en =1'b1;
|
rd_mem_en =1'b1;
|
if(m_ack_i) begin
|
if(m_ack_i) begin
|
wb_cap_rd=1'b1;
|
wb_cap_rd=1'b1;
|
ns=IDEAL;
|
ns=IDEAL;
|
//wb_addr_inc=1'b1;
|
//wb_addr_inc=1'b1;
|
end
|
end
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
|
|
//assign led={wb_addr[7:0], wb_wr_data[7:0]};
|
//assign led={wb_addr[7:0], wb_wr_data[7:0]};
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
module vjtag_ctrl #(
|
module vjtag_ctrl #(
|
parameter DW=32,
|
parameter DW=32,
|
parameter STW=2, // status width <= DW
|
parameter STW=2, // status width <= DW
|
parameter VJTAG_INDEX=126
|
parameter VJTAG_INDEX=126
|
|
|
)(
|
)(
|
clk,
|
clk,
|
reset,
|
reset,
|
data_out,
|
data_out,
|
data_in,
|
data_in,
|
status_i,
|
status_i,
|
wb_wr_addr_en,
|
wb_wr_addr_en,
|
wb_wr_data_en,
|
wb_wr_data_en,
|
wb_rd_data_en
|
wb_rd_data_en
|
);
|
);
|
|
|
//IO declaration
|
//IO declaration
|
input reset,clk;
|
input reset,clk;
|
output [DW-1 :0] data_out;
|
output [DW-1 :0] data_out;
|
input [DW-1 :0] data_in;
|
input [DW-1 :0] data_in;
|
input [STW-1 :0] status_i;
|
input [STW-1 :0] status_i;
|
output wb_wr_addr_en, wb_wr_data_en, wb_rd_data_en;
|
output wb_wr_addr_en, wb_wr_data_en, wb_rd_data_en;
|
|
|
|
|
//vjtag vjtag signals declaration
|
//vjtag vjtag signals declaration
|
wire [2:0] ir_out , ir_in;
|
wire [2:0] ir_out , ir_in;
|
wire tdo, tck, tdi;
|
wire tdo, tck, tdi;
|
wire cdr ,cir,e1dr,e2dr,pdr,sdr,udr,uir;
|
wire cdr ,cir,e1dr,e2dr,pdr,sdr,udr,uir;
|
|
|
|
|
vjtag #(
|
vjtag #(
|
.VJTAG_INDEX(VJTAG_INDEX)
|
.VJTAG_INDEX(VJTAG_INDEX)
|
)
|
)
|
vjtag_inst (
|
vjtag_inst (
|
.ir_out ( ir_out ),
|
.ir_out ( ir_out ),
|
.tdo ( tdo ),
|
.tdo ( tdo ),
|
.ir_in ( ir_in ),
|
.ir_in ( ir_in ),
|
.tck ( tck ),
|
.tck ( tck ),
|
.tdi ( tdi ),
|
.tdi ( tdi ),
|
.virtual_state_cdr ( cdr ),
|
.virtual_state_cdr ( cdr ),
|
.virtual_state_cir ( cir ),
|
.virtual_state_cir ( cir ),
|
.virtual_state_e1dr ( e1dr ),
|
.virtual_state_e1dr ( e1dr ),
|
.virtual_state_e2dr ( e2dr ),
|
.virtual_state_e2dr ( e2dr ),
|
.virtual_state_pdr ( pdr ),
|
.virtual_state_pdr ( pdr ),
|
.virtual_state_sdr ( sdr ),
|
.virtual_state_sdr ( sdr ),
|
.virtual_state_udr ( udr ),
|
.virtual_state_udr ( udr ),
|
.virtual_state_uir ( uir )
|
.virtual_state_uir ( uir )
|
);
|
);
|
|
|
|
|
// IR states
|
// IR states
|
localparam [2:0] UPDATE_WB_ADDR = 3'b111,
|
localparam [2:0] UPDATE_WB_ADDR = 3'b111,
|
UPDATE_WB_WR_DATA = 3'b110,
|
UPDATE_WB_WR_DATA = 3'b110,
|
UPDATE_WB_RD_DATA = 3'b101,
|
UPDATE_WB_RD_DATA = 3'b101,
|
RD_STATUS =3'b100,
|
RD_STATUS =3'b100,
|
BYPASS = 3'b000;
|
BYPASS = 3'b000;
|
|
|
|
|
// internal registers
|
// internal registers
|
reg [2:0] ir;
|
reg [2:0] ir;
|
reg bypass_reg;
|
reg bypass_reg;
|
reg [DW-1 : 0] shift_buffer,shift_buffer_next;
|
reg [DW-1 : 0] shift_buffer,shift_buffer_next;
|
reg cdr_delayed,sdr_delayed;
|
reg cdr_delayed,sdr_delayed;
|
|
|
|
|
|
|
/*
|
/*
|
always @(negedge tck)
|
always @(negedge tck)
|
begin
|
begin
|
// Delay the CDR signal by one half clock cycle
|
// Delay the CDR signal by one half clock cycle
|
cdr_delayed = cdr;
|
cdr_delayed = cdr;
|
sdr_delayed = sdr;
|
sdr_delayed = sdr;
|
end
|
end
|
*/
|
*/
|
|
|
assign ir_out = ir_in; // Just pass the IR out
|
assign ir_out = ir_in; // Just pass the IR out
|
assign tdo = (ir == BYPASS) ? bypass_reg : shift_buffer[0];
|
assign tdo = (ir == BYPASS) ? bypass_reg : shift_buffer[0];
|
assign data_out = shift_buffer;
|
assign data_out = shift_buffer;
|
|
|
|
|
|
`ifdef SYNC_RESET_MODE
|
|
always @ (posedge tck )begin
|
|
`else
|
|
always @ (posedge tck or posedge reset)begin
|
|
`endif
|
|
|
|
|
always @(posedge tck or posedge reset)
|
|
begin
|
|
if (reset)begin
|
if (reset)begin
|
ir <= 3'b000;
|
ir <= 3'b000;
|
bypass_reg<=1'b0;
|
bypass_reg<=1'b0;
|
shift_buffer<={DW{1'b0}};
|
shift_buffer<={DW{1'b0}};
|
|
|
end else begin
|
end else begin
|
if( uir ) ir <= ir_in; // Capture the instruction provided
|
if( uir ) ir <= ir_in; // Capture the instruction provided
|
bypass_reg <= tdi;
|
bypass_reg <= tdi;
|
shift_buffer<=shift_buffer_next;
|
shift_buffer<=shift_buffer_next;
|
|
|
end
|
end
|
end
|
end
|
|
|
|
|
|
|
always @ (*)begin
|
always @ (*)begin
|
shift_buffer_next=shift_buffer;
|
shift_buffer_next=shift_buffer;
|
|
|
if( sdr ) shift_buffer_next={tdi,shift_buffer[DW-1:1]};// shift buffer
|
if( sdr ) shift_buffer_next={tdi,shift_buffer[DW-1:1]};// shift buffer
|
case(ir)
|
case(ir)
|
RD_STATUS:begin
|
RD_STATUS:begin
|
if( cdr ) shift_buffer_next[STW-1 : 0] = status_i;
|
if( cdr ) shift_buffer_next[STW-1 : 0] = status_i;
|
end
|
end
|
default: begin
|
default: begin
|
if( cdr ) shift_buffer_next = data_in;
|
if( cdr ) shift_buffer_next = data_in;
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
|
|
|
|
|
|
reg wb_wr_addr1, wb_wr_data1, wb_rd_data1;
|
reg wb_wr_addr1, wb_wr_data1, wb_rd_data1;
|
//always @(posedge tck or posedge reset)
|
//always @(posedge tck or posedge reset)
|
always @(*)
|
always @(*)
|
begin
|
begin
|
//if( reset ) begin
|
//if( reset ) begin
|
// wb_wr_addr1<=1'b0;
|
// wb_wr_addr1<=1'b0;
|
// wb_wr_data1<=1'b0;
|
// wb_wr_data1<=1'b0;
|
//end else begin
|
//end else begin
|
wb_wr_addr1=(ir== UPDATE_WB_ADDR || ir== UPDATE_WB_RD_DATA) & udr;
|
wb_wr_addr1=(ir== UPDATE_WB_ADDR || ir== UPDATE_WB_RD_DATA) & udr;
|
wb_wr_data1=(ir== UPDATE_WB_WR_DATA && udr );
|
wb_wr_data1=(ir== UPDATE_WB_WR_DATA && udr );
|
wb_rd_data1=(ir==UPDATE_WB_RD_DATA && cdr);
|
wb_rd_data1=(ir==UPDATE_WB_RD_DATA && cdr);
|
//end
|
//end
|
end
|
end
|
|
|
reg wb_wr_addr2, wb_wr_data2, wb_rd_data2;
|
reg wb_wr_addr2, wb_wr_data2, wb_rd_data2;
|
reg wb_wr_addr3, wb_wr_data3, wb_rd_data3;
|
reg wb_wr_addr3, wb_wr_data3, wb_rd_data3;
|
|
|
always @(posedge clk or posedge reset)
|
`ifdef SYNC_RESET_MODE
|
begin
|
always @ (posedge clk )begin
|
|
`else
|
|
always @ (posedge clk or posedge reset)begin
|
|
`endif
|
|
|
if( reset ) begin
|
if( reset ) begin
|
wb_wr_addr2<=1'b0;
|
wb_wr_addr2<=1'b0;
|
wb_wr_data2<=1'b0;
|
wb_wr_data2<=1'b0;
|
wb_wr_addr3<=1'b0;
|
wb_wr_addr3<=1'b0;
|
wb_wr_data3<=1'b0;
|
wb_wr_data3<=1'b0;
|
wb_rd_data2<=1'b0;
|
wb_rd_data2<=1'b0;
|
wb_rd_data3<=1'b0;
|
wb_rd_data3<=1'b0;
|
end else begin
|
end else begin
|
wb_wr_addr2<=wb_wr_addr1;
|
wb_wr_addr2<=wb_wr_addr1;
|
wb_wr_data2<=wb_wr_data1;
|
wb_wr_data2<=wb_wr_data1;
|
wb_wr_addr3<=wb_wr_addr2;
|
wb_wr_addr3<=wb_wr_addr2;
|
wb_wr_data3<=wb_wr_data2;
|
wb_wr_data3<=wb_wr_data2;
|
wb_rd_data2<=wb_rd_data1;
|
wb_rd_data2<=wb_rd_data1;
|
wb_rd_data3<=wb_rd_data2;
|
wb_rd_data3<=wb_rd_data2;
|
end
|
end
|
end
|
end
|
|
|
assign wb_wr_addr_en =(wb_wr_addr2 & ~wb_wr_addr3);
|
assign wb_wr_addr_en =(wb_wr_addr2 & ~wb_wr_addr3);
|
assign wb_wr_data_en =(wb_wr_data2 & ~wb_wr_data3);
|
assign wb_wr_data_en =(wb_wr_data2 & ~wb_wr_data3);
|
assign wb_rd_data_en =(wb_rd_data2 & ~wb_rd_data3);
|
assign wb_rd_data_en =(wb_rd_data2 & ~wb_rd_data3);
|
endmodule
|
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|