1 |
22 |
bporcella |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
2 |
|
|
//// ////
|
3 |
|
|
//// file name: z80_bist_logic.v ////
|
4 |
|
|
//// description: built in self test logic ////
|
5 |
|
|
//// project: wb_z80 ////
|
6 |
|
|
//// ////
|
7 |
|
|
//// ////
|
8 |
|
|
//// Author: B.J. Porcella ////
|
9 |
|
|
//// bporcella@sbcglobal.net ////
|
10 |
|
|
//// ////
|
11 |
|
|
//// ////
|
12 |
|
|
//// ////
|
13 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
14 |
|
|
//// ////
|
15 |
|
|
//// Copyright (C) 2000-2002 B.J. Porcella ////
|
16 |
|
|
//// Real Time Solutions ////
|
17 |
|
|
//// ////
|
18 |
|
|
//// ////
|
19 |
|
|
//// This source file may be used and distributed without ////
|
20 |
|
|
//// restriction provided that this copyright statement is not ////
|
21 |
|
|
//// removed from the file and that any derivative work contains ////
|
22 |
|
|
//// the original copyright notice and the associated disclaimer. ////
|
23 |
|
|
//// ////
|
24 |
|
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
25 |
|
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
26 |
|
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
27 |
|
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
28 |
|
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
29 |
|
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
30 |
|
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
31 |
|
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
32 |
|
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
33 |
|
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
34 |
|
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
35 |
|
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
36 |
|
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
37 |
|
|
//// ////
|
38 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
39 |
|
|
// CVS Log
|
40 |
|
|
//
|
41 |
27 |
bporcella |
// $Id: z80_bist_logic.v,v 1.2 2004-05-27 14:23:36 bporcella Exp $
|
42 |
22 |
bporcella |
//
|
43 |
27 |
bporcella |
// $Date: 2004-05-27 14:23:36 $
|
44 |
|
|
// $Revision: 1.2 $
|
45 |
22 |
bporcella |
// $Author: bporcella $
|
46 |
|
|
// $Locker: $
|
47 |
|
|
// $State: Exp $
|
48 |
|
|
//
|
49 |
|
|
// Change History:
|
50 |
|
|
// $Log: not supported by cvs2svn $
|
51 |
27 |
bporcella |
// Revision 1.1 2004/05/13 14:57:35 bporcella
|
52 |
|
|
// testbed files
|
53 |
|
|
//
|
54 |
22 |
bporcella |
// Revision 1.1.1.1 2004/04/13 23:47:42 bporcella
|
55 |
|
|
// import first files
|
56 |
|
|
//
|
57 |
|
|
//
|
58 |
|
|
//
|
59 |
27 |
bporcella |
// There are a few things here:
|
60 |
|
|
// 1) A register to sequence the bist signals. A bist is run after rst, and the program
|
61 |
|
|
// indicates completion by setting bist_ack.
|
62 |
|
|
// 2) A simple I/O device to aid in I/O instruction testing. The input device sequences
|
63 |
|
|
// through a set of "interesting" data. The output device simply displays anything
|
64 |
|
|
// written to it.
|
65 |
|
|
// 3) A very simple interrupt generator. I guess this could be used as a clock in a real
|
66 |
|
|
// system. Priority logic needs some work if that is to be done.
|
67 |
|
|
//
|
68 |
|
|
// Note that if thes bist is to be
|
69 |
22 |
bporcella |
// actually synthesized a different method of loading the core SRAM
|
70 |
|
|
// (eq from external PROM) must be implemented.
|
71 |
|
|
//
|
72 |
|
|
//-------1---------2---------3--------Module Name and Port List------7---------8---------9--------0
|
73 |
|
|
module z80_bist_logic( bist_err_o,
|
74 |
|
|
bist_ack_o,
|
75 |
27 |
bporcella |
wb_dat_o ,
|
76 |
|
|
wb_ack_o ,
|
77 |
|
|
int_req_o ,
|
78 |
22 |
bporcella |
wb_adr_i ,
|
79 |
|
|
wb_dat_i ,
|
80 |
|
|
wb_we_i ,
|
81 |
|
|
wb_cyc_i ,
|
82 |
|
|
wb_stb_i ,
|
83 |
|
|
wb_clk_i ,
|
84 |
|
|
wb_tga_i ,
|
85 |
27 |
bporcella |
int_req_i ,
|
86 |
22 |
bporcella |
wb_rst_i );
|
87 |
|
|
|
88 |
|
|
|
89 |
|
|
//-------1---------2---------3--------Output Ports---------6---------7---------8---------9--------0
|
90 |
27 |
bporcella |
output bist_err_o;
|
91 |
|
|
output bist_ack_o;
|
92 |
|
|
output [7:0] wb_dat_o;
|
93 |
|
|
output wb_ack_o;
|
94 |
|
|
output int_req_o;
|
95 |
22 |
bporcella |
//-------1---------2---------3--------Input Ports----------6---------7---------8---------9--------0
|
96 |
|
|
|
97 |
|
|
input [15:0] wb_adr_i;
|
98 |
|
|
input wb_we_i;
|
99 |
|
|
input wb_cyc_i;
|
100 |
|
|
input wb_stb_i;
|
101 |
|
|
input [1:0] wb_tga_i;
|
102 |
|
|
input wb_clk_i;
|
103 |
|
|
input wb_rst_i;
|
104 |
|
|
input [7:0] wb_dat_i;
|
105 |
27 |
bporcella |
input int_req_i;
|
106 |
22 |
bporcella |
|
107 |
|
|
|
108 |
|
|
//-------1---------2---------3--------Parameters-----------6---------7---------8---------9--------0
|
109 |
|
|
//-------1---------2---------3--------Wires------5---------6---------7---------8---------9--------0
|
110 |
|
|
//-------1---------2---------3--------Registers--5---------6---------7---------8---------9--------0
|
111 |
27 |
bporcella |
reg [2:0] bist_reg;
|
112 |
22 |
bporcella |
integer i;
|
113 |
27 |
bporcella |
reg wb_ack_o;
|
114 |
|
|
reg [7:0] out_state;
|
115 |
|
|
reg [9:0] int_count;
|
116 |
|
|
reg int_req;
|
117 |
|
|
wire int_ack;
|
118 |
|
|
wire bist_int_en;
|
119 |
|
|
|
120 |
22 |
bporcella |
//-------1---------2---------3--------Assignments----------6---------7---------8---------9--------0
|
121 |
|
|
assign bist_err_o = bist_reg[1];
|
122 |
|
|
assign bist_ack_o = bist_reg[0];
|
123 |
27 |
bporcella |
assign bist_int_en = bist_reg[2];
|
124 |
|
|
wire clk = wb_clk_i;
|
125 |
|
|
wire rst = wb_rst_i;
|
126 |
|
|
assign int_req_o = int_req_i | int_req & bist_int_en;
|
127 |
22 |
bporcella |
//-------1---------2---------3--------State Machines-------6---------7---------8---------9--------0
|
128 |
27 |
bporcella |
// The following parameters are "known" to the instruction test program.
|
129 |
|
|
// If you change them change the test program accorcingly.
|
130 |
|
|
//
|
131 |
|
|
parameter INT_OFFSET = 8'hfe; // int device provides offset to last entry of int table.
|
132 |
|
|
parameter BIST_ADR = 16'hffff ; // address of bist register
|
133 |
|
|
parameter MY_IO_ADR = 8'h20 ; // Map to " " for minor reasons related to "embedded test"
|
134 |
22 |
bporcella |
|
135 |
27 |
bporcella |
|
136 |
|
|
parameter TAG_MEM = 2'b00,
|
137 |
|
|
TAG_IO = 2'b01, // need to review general wb usage to undrstand how best to
|
138 |
|
|
TAG_INT = 2'b10; // document this.
|
139 |
|
|
|
140 |
|
|
|
141 |
|
|
|
142 |
|
|
|
143 |
|
|
|
144 |
|
|
// ----------------- a pretty simple I/O device ----------------------------------
|
145 |
|
|
|
146 |
|
|
wire a2io = (wb_adr_i[7:0] == MY_IO_ADR) & wb_stb_i & wb_cyc_i & (wb_tga_i == TAG_IO);
|
147 |
|
|
wire a2bist = (wb_adr_i == BIST_ADR) & wb_stb_i & wb_cyc_i & (wb_tga_i == TAG_MEM);
|
148 |
|
|
assign int_ack = wb_stb_i & wb_cyc_i & (wb_tga_i == TAG_INT);
|
149 |
|
|
|
150 |
|
|
|
151 |
|
|
always @(posedge clk or posedge rst)
|
152 |
|
|
begin
|
153 |
|
|
if (wb_rst_i ) wb_ack_o <= 1'b0;
|
154 |
|
|
else if((a2io | a2bist | int_ack) & !wb_ack_o) wb_ack_o <= 1'b1;
|
155 |
|
|
else wb_ack_o <= 1'b0;
|
156 |
|
|
end
|
157 |
|
|
|
158 |
|
|
// the "output" device - output simply displays the data written --
|
159 |
|
|
always @(posedge clk or posedge rst)
|
160 |
|
|
if (a2io & wb_we_i & wb_ack_o) $write("%s",wb_dat_i);
|
161 |
|
|
|
162 |
|
|
// the "input" device --------------------------------------------------
|
163 |
|
|
//
|
164 |
|
|
// input cycles through
|
165 |
|
|
// various interesting data patterens as used by the instruction test
|
166 |
|
|
// namely 7f 55 80 0 ff aa
|
167 |
|
|
|
168 |
|
|
assign wb_dat_o = int_ack ? INT_OFFSET : out_state;
|
169 |
|
|
|
170 |
|
|
always @(posedge clk or posedge rst)
|
171 |
|
|
begin
|
172 |
|
|
if (wb_rst_i) out_state <= 8'h7f;
|
173 |
|
|
else if (a2io & !wb_we_i & wb_ack_o)
|
174 |
|
|
case (out_state)
|
175 |
|
|
8'h7f: out_state <= 8'h55 ;
|
176 |
|
|
8'h55: out_state <= 8'h80 ;
|
177 |
|
|
8'h80: out_state <= 8'h00 ;
|
178 |
|
|
8'h00: out_state <= 8'hff ;
|
179 |
|
|
8'hff: out_state <= 8'haa ;
|
180 |
|
|
8'haa: out_state <= 8'h7f ;
|
181 |
|
|
default: out_state <= 8'h7f ;
|
182 |
|
|
endcase
|
183 |
|
|
end
|
184 |
|
|
|
185 |
|
|
|
186 |
|
|
//----- memory mapped register ----------- for bist control
|
187 |
22 |
bporcella |
// my address is selected as memory mapped to top of SDRAM.
|
188 |
|
|
// any system implementation may choose to modify this.
|
189 |
|
|
|
190 |
|
|
wire wb_wr = wb_cyc_i & wb_stb_i & wb_we_i;
|
191 |
27 |
bporcella |
wire my_adr = (wb_tga_i == 2'b00) & ( wb_adr_i == BIST_ADR);
|
192 |
|
|
|
193 |
22 |
bporcella |
always @(posedge wb_clk_i or wb_rst_i)
|
194 |
27 |
bporcella |
if (wb_rst_i) bist_reg <= 3'b0;
|
195 |
|
|
else if (my_adr & wb_wr & wb_ack_o) bist_reg <= wb_dat_i[2:0];
|
196 |
22 |
bporcella |
|
197 |
|
|
|
198 |
|
|
initial
|
199 |
|
|
begin
|
200 |
27 |
bporcella |
$display("BL messages from Bist logic TB messages from test bench - others from test" );
|
201 |
|
|
$display("BL dump a few memory locations to be sure initialization is sane") ;
|
202 |
|
|
$readmemh( "readmem.txt", z80_testbed.i_z80_core_top.i_z80_sram.mem );
|
203 |
22 |
bporcella |
// be sure at least some of the data got properly loaded.
|
204 |
|
|
for (i=0; i<10; i=i+1)
|
205 |
27 |
bporcella |
$display( "BL mem [%0d] = %h", i, z80_testbed.i_z80_core_top.i_z80_sram.mem[i]);
|
206 |
22 |
bporcella |
end
|
207 |
|
|
|
208 |
27 |
bporcella |
//--------------------- the interrupt device ------------------------------
|
209 |
|
|
|
210 |
|
|
always @(posedge wb_clk_i or wb_rst_i)
|
211 |
|
|
if (wb_rst_i) int_count <=10'h0;
|
212 |
|
|
else int_count <= int_count + 10'h1;
|
213 |
|
|
|
214 |
|
|
always @(posedge wb_clk_i or wb_rst_i)
|
215 |
|
|
if (wb_rst_i) int_req <= 1'b0;
|
216 |
|
|
else if (int_count==10'h3ff) int_req <= 1'b1;
|
217 |
|
|
else if ( int_ack ) int_req <= 1'b0;
|
218 |
22 |
bporcella |
endmodule
|