1 |
131 |
jt_eaton |
/**********************************************************************/
|
2 |
|
|
/* */
|
3 |
|
|
/* ------- */
|
4 |
|
|
/* / SOC \ */
|
5 |
|
|
/* / GEN \ */
|
6 |
|
|
/* / SIM \ */
|
7 |
|
|
/* ============== */
|
8 |
|
|
/* | | */
|
9 |
|
|
/* |____________| */
|
10 |
|
|
/* */
|
11 |
|
|
/* JTAG Hoset model for simulations */
|
12 |
|
|
/* */
|
13 |
|
|
/* */
|
14 |
|
|
/* Author(s): */
|
15 |
|
|
/* - John Eaton, jt_eaton@opencores.org */
|
16 |
|
|
/* */
|
17 |
|
|
/**********************************************************************/
|
18 |
|
|
/* */
|
19 |
|
|
/* Copyright (C) <2010> <Ouabache Design Works> */
|
20 |
|
|
/* */
|
21 |
|
|
/* This source file may be used and distributed without */
|
22 |
|
|
/* restriction provided that this copyright statement is not */
|
23 |
|
|
/* removed from the file and that any derivative work contains */
|
24 |
|
|
/* the original copyright notice and the associated disclaimer. */
|
25 |
|
|
/* */
|
26 |
|
|
/* This source file is free software; you can redistribute it */
|
27 |
|
|
/* and/or modify it under the terms of the GNU Lesser General */
|
28 |
|
|
/* Public License as published by the Free Software Foundation; */
|
29 |
|
|
/* either version 2.1 of the License, or (at your option) any */
|
30 |
|
|
/* later version. */
|
31 |
|
|
/* */
|
32 |
|
|
/* This source is distributed in the hope that it will be */
|
33 |
|
|
/* useful, but WITHOUT ANY WARRANTY; without even the implied */
|
34 |
|
|
/* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR */
|
35 |
|
|
/* PURPOSE. See the GNU Lesser General Public License for more */
|
36 |
|
|
/* details. */
|
37 |
|
|
/* */
|
38 |
|
|
/* You should have received a copy of the GNU Lesser General */
|
39 |
|
|
/* Public License along with this source; if not, download it */
|
40 |
|
|
/* from http://www.opencores.org/lgpl.shtml */
|
41 |
|
|
/* */
|
42 |
|
|
/**********************************************************************/
|
43 |
|
|
module
|
44 |
|
|
jtag_model_def
|
45 |
|
|
#( parameter
|
46 |
|
|
DIVCNT=4'h1,
|
47 |
|
|
SIZE=4)
|
48 |
|
|
(
|
49 |
|
|
input wire clk,
|
50 |
|
|
input wire reset,
|
51 |
|
|
input wire tdi,
|
52 |
|
|
output reg tclk,
|
53 |
|
|
output reg tdo,
|
54 |
|
|
output reg tms,
|
55 |
|
|
output reg trst_n);
|
56 |
|
|
reg tclk_enable;
|
57 |
|
|
reg [SIZE-1:0] tclk_counter;
|
58 |
|
|
wire next_tclk_edge;
|
59 |
|
|
wire next_tclk_pos_edge;
|
60 |
|
|
wire next_tclk_neg_edge;
|
61 |
|
|
assign next_tclk_edge = (tclk_counter == 4'h0);
|
62 |
|
|
assign next_tclk_pos_edge = next_tclk_edge && (!tclk) ;
|
63 |
|
|
assign next_tclk_neg_edge = next_tclk_edge && ( tclk) ;
|
64 |
|
|
always@(posedge clk)
|
65 |
|
|
if(reset) tclk_counter <= DIVCNT;
|
66 |
|
|
else
|
67 |
|
|
if(|tclk_counter) tclk_counter <= tclk_counter-4'h1;
|
68 |
|
|
else tclk_counter <= DIVCNT;
|
69 |
|
|
always@(posedge clk)
|
70 |
|
|
if(reset) tclk <= 1'b0;
|
71 |
|
|
else
|
72 |
|
|
if(!tclk_enable) tclk <= tclk;
|
73 |
|
|
else
|
74 |
|
|
if( next_tclk_pos_edge ) tclk <= 1'b1;
|
75 |
|
|
else
|
76 |
|
|
if( next_tclk_neg_edge ) tclk <= 1'b0;
|
77 |
|
|
else tclk <= tclk;
|
78 |
|
|
|
79 |
|
|
reg actual;
|
80 |
|
|
initial
|
81 |
|
|
begin
|
82 |
|
|
tclk_enable <= 1'b0;
|
83 |
|
|
tclk <= 1'b0;
|
84 |
|
|
tdo <= 1'b1;
|
85 |
|
|
tms <= 1'b1;
|
86 |
|
|
trst_n <= 1'b0;
|
87 |
|
|
end
|
88 |
|
|
task automatic next;
|
89 |
|
|
input [31:0] num;
|
90 |
|
|
repeat (num) @ (posedge clk);
|
91 |
|
|
endtask
|
92 |
|
|
task enable_tclk;
|
93 |
|
|
begin
|
94 |
|
|
tclk_enable <= 1'b1;
|
95 |
|
|
end
|
96 |
|
|
endtask
|
97 |
|
|
task enable_trst_n;
|
98 |
|
|
begin
|
99 |
|
|
Clk_bit(1,1,actual);
|
100 |
|
|
Clk_bit(1,1,actual);
|
101 |
|
|
Clk_bit(1,1,actual);
|
102 |
|
|
Clk_bit(1,1,actual);
|
103 |
|
|
Clk_bit(1,1,actual);
|
104 |
|
|
trst_n <= 1'b1;
|
105 |
|
|
Clk_bit(1,1,actual);
|
106 |
|
|
end
|
107 |
|
|
endtask
|
108 |
|
|
task enable_reset;
|
109 |
|
|
begin
|
110 |
|
|
Clk_bit(1,0,actual);
|
111 |
|
|
Clk_bit(1,0,actual);
|
112 |
|
|
Clk_bit(1,0,actual);
|
113 |
|
|
Clk_bit(1,0,actual);
|
114 |
|
|
Clk_bit(1,0,actual);
|
115 |
|
|
Clk_bit(1,0,actual);
|
116 |
|
|
Clk_bit(1,0,actual);
|
117 |
|
|
Clk_bit(1,0,actual);
|
118 |
|
|
end
|
119 |
|
|
endtask
|
120 |
|
|
task init;
|
121 |
|
|
begin
|
122 |
|
|
Clk_bit(0,0,actual);
|
123 |
|
|
Clk_bit(0,0,actual);
|
124 |
|
|
Clk_bit(0,0,actual);
|
125 |
|
|
Clk_bit(0,0,actual);
|
126 |
|
|
Clk_bit(0,0,actual);
|
127 |
|
|
Clk_bit(0,0,actual);
|
128 |
|
|
Clk_bit(0,0,actual);
|
129 |
|
|
Clk_bit(0,0,actual);
|
130 |
|
|
end
|
131 |
|
|
endtask
|
132 |
|
|
|
133 |
|
|
task Clk_bit;
|
134 |
|
|
input TMS;
|
135 |
|
|
input TDO;
|
136 |
|
|
output ACT;
|
137 |
|
|
begin
|
138 |
|
|
while (next_tclk_neg_edge != 1)
|
139 |
|
|
begin
|
140 |
|
|
next(1);
|
141 |
|
|
end
|
142 |
|
|
if(TMS) tms <= 1'b1;
|
143 |
|
|
else tms <= 1'b0;
|
144 |
|
|
if ( TDO == 1 ) tdo <= 1'b1;
|
145 |
|
|
else if( TDO == 0 ) tdo <= 1'b0;
|
146 |
|
|
else tdo <= 1'bx;
|
147 |
|
|
while (next_tclk_pos_edge != 1)
|
148 |
|
|
begin
|
149 |
|
|
next(1);
|
150 |
|
|
end
|
151 |
|
|
ACT = tdi;
|
152 |
|
|
end
|
153 |
|
|
endtask
|
154 |
|
|
/******************************************************************************/
|
155 |
|
|
/* LoadTapInst (<Inst>); */
|
156 |
|
|
/******************************************************************************/
|
157 |
|
|
task LoadTapInst; // Load a Tap Instruction that uses the Boundary Register
|
158 |
|
|
parameter [15:0] JTAG_INST_LENGTH = 4;
|
159 |
|
|
input [JTAG_INST_LENGTH:1] Inst; // This task starts & ends with the Tap in the RT_IDLE state
|
160 |
|
|
input [JTAG_INST_LENGTH:1] Inst_Return; //
|
161 |
|
|
integer i;
|
162 |
|
|
reg [JTAG_INST_LENGTH:1] Ack;
|
163 |
|
|
begin
|
164 |
|
|
Clk_bit(1'b1,1'b0,actual); // Transition from RT_IDLE to SELECT_DR
|
165 |
|
|
Clk_bit(1'b1,1'b0,actual); // Transition from SELECT_DR to SELECT_IR
|
166 |
|
|
Clk_bit(1'b0,1'b0,actual); // Transition from SELECT_IR to CAPTURE_IR
|
167 |
|
|
Clk_bit(1'b0,1'b0,actual); // Transition from CAPTURE_IR to SHIFT_IR
|
168 |
|
|
for (i = 1; i <= JTAG_INST_LENGTH; i = i+1) // Shift in Inst
|
169 |
|
|
begin
|
170 |
|
|
Clk_bit(( i == JTAG_INST_LENGTH),Inst[i],Ack[i]);
|
171 |
|
|
end
|
172 |
|
|
$display ("%t %m LoadTapInst %b Expected %b Received %b " ,$realtime,Inst, Inst_Return, Ack );
|
173 |
|
|
if (Ack !== Inst_Return)
|
174 |
|
|
begin
|
175 |
|
|
cg.fail (" LoadTapInst receive error ");
|
176 |
|
|
end
|
177 |
|
|
Clk_bit(1'b1,1'b0,actual); // Transition from EXIT1_IR to UPDATE_IR
|
178 |
|
|
Clk_bit(1'b0,1'b0,actual);// Transition from UPDATE_IR to RT_IDLE
|
179 |
|
|
end
|
180 |
|
|
endtask // LoadTapInst
|
181 |
|
|
//***************************************************************************/
|
182 |
|
|
//* Shift Register
|
183 |
|
|
//***************************************************************************/
|
184 |
|
|
task automatic Shift_Register; // Initialize boundary register with outputs disabled
|
185 |
|
|
// This tasks starts at RT_IDLE and ends at SHIFT_DR
|
186 |
|
|
parameter [15:0] LENGTH = 100;
|
187 |
|
|
input length;
|
188 |
|
|
input [LENGTH:1] Dataout;
|
189 |
|
|
integer length;
|
190 |
|
|
integer i;
|
191 |
|
|
reg [LENGTH:1] DataBack;
|
192 |
|
|
begin
|
193 |
|
|
Clk_bit(1'b1,1'b0,actual);// Transition from RT_IDLE to SELECT_DR
|
194 |
|
|
Clk_bit(1'b0,1'b0,actual);// Transition from SELECT_DR to CAPTURE_DR
|
195 |
|
|
Clk_bit(1'b0,1'b0,actual);// Transition from CAPTURE_DR to SHIFT_DR
|
196 |
|
|
for (i = 1; i <= length; i = i+1)
|
197 |
|
|
Clk_bit((i==length),Dataout[i],DataBack[i]);
|
198 |
|
|
$display ("%t %m Shift_data -%d wr-%h rd-%h ",$realtime,length,Dataout[LENGTH:1],DataBack[LENGTH:1]);
|
199 |
|
|
Clk_bit(1'b1,1'b0,actual);//Transition from EXIT1-DR to UPDATE-DR
|
200 |
|
|
Clk_bit(1'b0,1'b0,actual);// Transition from UPDATE-DR to IDLE
|
201 |
|
|
end
|
202 |
|
|
endtask // ShiftRegister
|
203 |
|
|
task automatic Shift_Cmp_32; // Initialize boundary register with outputs disabled
|
204 |
|
|
// This tasks starts at RT_IDLE and ends at SHIFT_DR
|
205 |
|
|
parameter [15:0] LENGTH = 32;
|
206 |
|
|
input [LENGTH:1] Dataout;
|
207 |
|
|
input [LENGTH:1] DataExp;
|
208 |
|
|
integer i;
|
209 |
|
|
reg [LENGTH:1] DataBack;
|
210 |
|
|
begin
|
211 |
|
|
Clk_bit(1'b1,1'b0,actual);// Transition from RT_IDLE to SELECT_DR
|
212 |
|
|
Clk_bit(1'b0,1'b0,actual);// Transition from SELECT_DR to CAPTURE_DR
|
213 |
|
|
Clk_bit(1'b0,1'b0,actual);// Transition from CAPTURE_DR to SHIFT_DR
|
214 |
|
|
for (i = 1; i <= LENGTH; i = i+1)
|
215 |
|
|
Clk_bit((i==LENGTH),Dataout[i],DataBack[i]);
|
216 |
|
|
$display ("%t %m Shift_data_register wr-%h exp-%h rd-%h ",$realtime,Dataout,DataExp,DataBack );
|
217 |
|
|
if (DataBack !== DataExp )
|
218 |
|
|
begin
|
219 |
|
|
cg.fail (" Shift_cmp receive error ");
|
220 |
|
|
end
|
221 |
|
|
Clk_bit(1'b1,1'b0,actual);//Transition from EXIT1-DR to UPDATE-DR
|
222 |
|
|
Clk_bit(1'b0,1'b0,actual);// Transition from UPDATE-DR to IDLE
|
223 |
|
|
end
|
224 |
|
|
endtask // ShiftRegister
|
225 |
|
|
endmodule
|