Statistics
| Revision:

achd-soc / trunk / tests / FCManualBitstreamGeneration / main.cpp @ 1089

History | View | Annotate | Download (10.9 KB)

1
/***********************************************************************************************************************
2
*                                                                                                                      *
3
* UTICA softcore v0.1                                                                                                  *
4
*                                                                                                                      *
5
* Copyright (c) 2012-2013 Andrew D. Zonenberg                                                                          *
6
* All rights reserved.                                                                                                 *
7
*                                                                                                                      *
8
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the     *
9
* following conditions are met:                                                                                        *
10
*                                                                                                                      *
11
*    * Redistributions of source code must retain the above copyright notice, this list of conditions, and the         *
12
*      following disclaimer.                                                                                           *
13
*                                                                                                                      *
14
*    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the       *
15
*      following disclaimer in the documentation and/or other materials provided with the distribution.                *
16
*                                                                                                                      *
17
*    * Neither the name of the author nor the names of any contributors may be used to endorse or promote products     *
18
*      derived from this software without specific prior written permission.                                           *
19
*                                                                                                                      *
20
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   *
21
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
22
* THE AUTHORS BE HELD LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES        *
23
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR       *
24
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
25
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE       *
26
* POSSIBILITY OF SUCH DAMAGE.                                                                                          *
27
*                                                                                                                      *
28
***********************************************************************************************************************/
29

    
30
/**
31
        @file main.cpp
32
        @author Andrew D. Zonenberg
33
        @brief Flying Crowbar manual bitstream generation test
34
        
35
        Creates a bitstream in memory without using any Xilinx tools, writes it to the device, and verifies proper functionality.
36
 */
37
#include <string>
38
#include "../../src/jtaghal/jtaghal.h"
39
#include "../../src/jtaghal/XilinxCPLDBitstream.h"
40
#include "../../src/jtaghal/CPLDSerializer.h"
41
#include "../../src/jtaghal/CPLDBitstreamWriter.h"
42
#include "../../src/jtagboards/jtagboards.h"
43
#include "../../src/crowbar/crowbar.h"
44
#include "../../src/crowbar/FCCoolRunnerIIDevice.h"
45
#include "../../src/crowbar/FCCoolRunnerIINetlist.h"
46

    
47
using namespace std;
48

    
49
FCCoolRunnerIINetlist* GenerateNetlist(FCCoolRunnerIIDevice& device);
50
 
51
int main(int argc, char* argv[])
52
{
53
        int err_code = 0;
54
        try
55
        {
56
                //Connect to the server
57
                string server;
58
                string tty;
59
                int port = 0;
60
                for(int i=1; i<argc; i++)
61
                {
62
                        string s(argv[i]);
63
                        
64
                        if(s == "--port")
65
                                port = atoi(argv[++i]);
66
                        else if(s == "--server")
67
                                server = argv[++i];
68
                        else if(s == "--tty")
69
                                tty = argv[++i];
70
                        else
71
                        {
72
                                printf("Unrecognized command-line argument \"%s\", expected --server or --port\n", s.c_str());
73
                                return 1;
74
                        }
75
                }
76
                if( (server == "") || (port == 0) )
77
                {
78
                        throw JtagExceptionWrapper(
79
                                "No server or port name specified",
80
                                "",
81
                                JtagException::EXCEPTION_TYPE_GIGO);
82
                }
83
                NetworkedJtagInterface iface;
84
                iface.Connect(server, port);
85
                
86
                //Initialize the board
87
                CR2DevBoard board(&iface);
88
                board.InitializeBoard(true);
89
                
90
                //Sanity check that the interface is GPIO capable
91
                printf("Initializing GPIO interface...\n");
92
                if(!iface.IsGPIOCapable())
93
                {
94
                        throw JtagExceptionWrapper(
95
                                "JTAG interface should be GPIO capable, but isn't",
96
                                "",
97
                                JtagException::EXCEPTION_TYPE_GIGO);
98
                }
99
                printf("    Interface is GPIO capable (%d GPIO pins)\n", iface.GetGpioCount());
100
                
101
                //Get a few pointers
102
                //No need to validate at this point, InitializeBoard() made sure everything is OK
103
                CPLD* pcpld = dynamic_cast<CPLD*>(board.GetDefaultDevice());
104
                
105
                //Create the device
106
                printf("Initializing device...\n");
107
                string devname = "xc2c32a-6-vqg44";
108
                FCCoolRunnerIIDevice device(devname);
109
                
110
                //Generate the netlist programmatically
111
                printf("Generating netlist...\n");
112
                FCCoolRunnerIINetlist* netlist = GenerateNetlist(device);
113
                
114
                //Fit the netlist
115
                device.Fit(netlist);
116
                
117
                //Make a bitstream from the device
118
                printf("Generating bitstream...\n");
119
                XilinxCPLDBitstream bitstream;
120
                CPLDBitstreamWriter writer(&bitstream, board.GetDefaultDevice()->GetIDCode(), devname);
121
                device.SaveToBitstream(&writer);
122
                
123
                //Configure the device
124
                printf("Configuring device...\n");
125
                pcpld->Program(&bitstream);
126
                
127
                //Verify that it's configured
128
                if(!pcpld->IsProgrammed())
129
                {
130
                        throw JtagExceptionWrapper(
131
                                "CPLD should be configured but isn't",
132
                                "",
133
                                JtagException::EXCEPTION_TYPE_BOARD_FAULT);
134
                }
135
                
136
                /*
137
                        Set up pin configuration
138
                        
139
                        gpio[0] = output
140
                        gpio[1] = input
141
                        
142
                        The CPLD should function as a simple inverter.
143
                 */
144
                iface.SetGpioDirectionDeferred(0, true);
145
                iface.SetGpioDirectionDeferred(1, false);
146
                
147
                for(int i=0; i<10; i++)
148
                {
149
                        printf("    Testing dout=0\n");
150
                        iface.SetGpioValue(0, false);
151
                        if(!iface.GetGpioValue(1))
152
                        {
153
                                throw JtagExceptionWrapper(
154
                                        "    Expected din=1, got 0\n",
155
                                        "",
156
                                        JtagException::EXCEPTION_TYPE_BOARD_FAULT);
157
                        }
158
                        usleep(100 * 1000);
159
                        
160
                        printf("    Testing dout=1\n");
161
                        iface.SetGpioValue(0, true);
162
                        if(iface.GetGpioValue(1))
163
                        {
164
                                throw JtagExceptionWrapper(
165
                                        "    Expected din=0, got 1\n",
166
                                        "",
167
                                        JtagException::EXCEPTION_TYPE_BOARD_FAULT);
168
                        }
169
                        usleep(100 * 1000);
170
                }
171
                printf("OK\n");
172
                
173
                //DEBUG: Dump the resulting netlist somewhere
174
                //printf("\n\n\n");
175
                //device.Dump();
176
                //device.DumpRTL();
177
                
178
                //Clean up
179
                delete netlist;
180
        }
181
        
182
        catch(const JtagException& ex)
183
        {
184
                printf("%s\n", ex.GetDescription().c_str());
185
                err_code = 1;
186
        }
187
        
188
        return err_code;
189
}
190

    
191
/**
192
        @brief Generates a netlist as follows:
193
        
194
        input wire din;
195
        output wire dout;
196
        output wire led1;
197
        output wire led2;
198
        
199
        assign dout = ~din;
200
        assign led1 = din;
201
        assign led2 = ~din;
202
 */
203
FCCoolRunnerIINetlist* GenerateNetlist(FCCoolRunnerIIDevice& device)
204
{
205
        //Get the IOBs
206
        FCCoolRunnerIIIOB* iob_gpiol0 = static_cast<FCCoolRunnerIIIOB*>(device.GetIOBForPin("P8"));
207
        FCCoolRunnerIIIOB* iob_gpiol1 = static_cast<FCCoolRunnerIIIOB*>(device.GetIOBForPin("P6"));
208
        FCCoolRunnerIIIOB* iob_led1 = static_cast<FCCoolRunnerIIIOB*>(device.GetIOBForPin("P38"));
209
        FCCoolRunnerIIIOB* iob_led2 = static_cast<FCCoolRunnerIIIOB*>(device.GetIOBForPin("P37"));
210
        printf("IOB assignment\n");
211
        printf("    IOB for FTDI_GPIOL0 is at %s\n", iob_gpiol0->GetNamePrefix().c_str());
212
        printf("    IOB for FTDI_GPIOL1 is at %s\n", iob_gpiol1->GetNamePrefix().c_str());
213
        printf("    IOB for LED1 is at %s\n", iob_led1->GetNamePrefix().c_str());
214
        printf("    IOB for LED2 is at %s\n", iob_led2->GetNamePrefix().c_str());
215
        
216
        //GPIOL0: LVCMOS33 input
217
        iob_gpiol0->m_iostandard = FCCoolRunnerIIIOB::LVCMOS33;
218
        iob_gpiol0->SetInZ(FCCoolRunnerIIIOB::INZ_INPUT);
219
        iob_gpiol0->SetOE(FCCoolRunnerIIIOB::OE_FLOAT);
220
        iob_gpiol0->SetTerminationMode(FCCoolRunnerIIIOB::TERM_FLOAT);
221
        iob_gpiol0->m_bSchmittTriggerEnabled = false;
222
        
223
        //GPIOL1: unregistered LVCMOS33 output
224
        iob_gpiol1->m_iostandard = FCCoolRunnerIIIOB::LVCMOS33;
225
        iob_gpiol1->SetInZ(FCCoolRunnerIIIOB::INZ_FLOAT);
226
        iob_gpiol1->SetOE(FCCoolRunnerIIIOB::OE_OUTPUT);
227
        iob_gpiol1->m_outmode = FCCoolRunnerIIIOB::OUTPUT_DIRECT;
228
        iob_gpiol1->SetTerminationMode(FCCoolRunnerIIIOB::TERM_FLOAT);
229
        iob_gpiol1->SetSlewRate(FCCoolRunnerIIIOB::SLEW_FAST);
230
        iob_gpiol1->m_bSchmittTriggerEnabled = false;
231
        
232
        //LED1: unregistered LVCMOS33 output
233
        iob_led1->m_iostandard = FCCoolRunnerIIIOB::LVCMOS33;
234
        iob_led1->SetInZ(FCCoolRunnerIIIOB::INZ_FLOAT);
235
        iob_led1->SetOE(FCCoolRunnerIIIOB::OE_OUTPUT);
236
        iob_led1->m_outmode = FCCoolRunnerIIIOB::OUTPUT_DIRECT;
237
        iob_led1->SetTerminationMode(FCCoolRunnerIIIOB::TERM_FLOAT);
238
        iob_led1->SetSlewRate(FCCoolRunnerIIIOB::SLEW_SLOW);
239
        iob_led1->m_bSchmittTriggerEnabled = false;
240
        
241
        //LED2: unregistered LVCMOS33 output
242
        iob_led2->m_iostandard = FCCoolRunnerIIIOB::LVCMOS33;
243
        iob_led2->SetInZ(FCCoolRunnerIIIOB::INZ_FLOAT);
244
        iob_led2->SetOE(FCCoolRunnerIIIOB::OE_OUTPUT);
245
        iob_led2->m_outmode = FCCoolRunnerIIIOB::OUTPUT_DIRECT;
246
        iob_led2->SetTerminationMode(FCCoolRunnerIIIOB::TERM_FLOAT);
247
        iob_led2->SetSlewRate(FCCoolRunnerIIIOB::SLEW_SLOW);
248
        iob_led2->m_bSchmittTriggerEnabled = false;
249
        
250
        //Create the netlist
251
        FCCoolRunnerIINetlist* netlist = new FCCoolRunnerIINetlist(&device);
252
        
253
        //Product terms
254
        FCCoolRunnerIIProductTerm* pterm_din = netlist->CreateProductTerm();
255
        FCCoolRunnerIIProductTerm* pterm_din_n = netlist->CreateProductTerm();
256
        pterm_din->AddInput(iob_gpiol0, false);
257
        pterm_din_n->AddInput(iob_gpiol0, true);
258
        
259
        //OR terms
260
        FCCoolRunnerIIOrTerm* orterm_dout = netlist->CreateOrTerm();
261
        FCCoolRunnerIIOrTerm* orterm_led1 = netlist->CreateOrTerm();
262
        FCCoolRunnerIIOrTerm* orterm_led2 = netlist->CreateOrTerm();
263
        orterm_dout->m_pterms.push_back(pterm_din_n);
264
        orterm_led1->m_pterms.push_back(pterm_din);
265
        orterm_led2->m_pterms.push_back(pterm_din_n);
266
        
267
        //Macrocells
268
        FCCoolRunnerIINetlistMacrocell* mcell_dout = netlist->CreateMacrocell(orterm_dout, iob_gpiol1);
269
        FCCoolRunnerIINetlistMacrocell* mcell_led0 = netlist->CreateMacrocell(orterm_led1, iob_led1);
270
        FCCoolRunnerIINetlistMacrocell* mcell_led1 = netlist->CreateMacrocell(orterm_led2, iob_led2);
271
        
272
        //Macrocell configuration - XOR passthrough, ignore the flipflop
273
        mcell_dout->m_xorin = FCCoolRunnerIIMacrocell::XORIN_ZERO;
274
        mcell_led0->m_xorin = FCCoolRunnerIIMacrocell::XORIN_ZERO;
275
        mcell_led1->m_xorin = FCCoolRunnerIIMacrocell::XORIN_ZERO;
276
        
277
        //Done
278
        return netlist;
279
}