1`timescale 1ns / 1ps 2/* 3 * This software is Copyright (c) 2016 Denis Burykin 4 * [denis_burykin yahoo com], [denis-burykin2014 yandex ru] 5 * and it is hereby released to the general public under the following terms: 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted. 8 * 9 */ 10 11//*********************************************************** 12// 13// Vendor Command / Vendor Request feature 14// Commands or requests are sent to EZ-USB via USB EP0 15// and handled by EZ-USB processor. 16// 17//*********************************************************** 18 19//*********************************************************** 20// 21// New feature: cmd 0x00 disables the interface, allows 22// usage of raw I/O port PC[7:0]. A pulse on clk_vcr_addr returns from raw mode. 23// 24// There's up to 256 VCR addresses (subsystems) for read or(and) write. 25// Sequential multi-byte read or/and write is possible. 26// For some actions, there's no need to read or write, just select address. 27// 28// EZ-USB uses 11 lines to FPGA. Typical exchange is as follows: 29// 1. set direction towards FPGA (vcr_dir=0). Assert CPU I/O controls accordingly. 30// 2. assert address on [7:0] vcr_inout. 31// 3. assert vcr_set_addr, then deassert vcr_set_addr. This selects address. 32// Optionally write: 33// 4. setup data byte on [7:0] vcr_inout. 34// 5. assert vcr_set_data, then deassert vcr_set_data. This performs write of the byte from step 4. 35// 6. go to step 4 if nesessary. 36// Optionally read: 37// 7. set direction for input from FPGA (vcr_dir=1). Assert CPU I/O controls accordingly. 38// 8. read data byte from [7:0] vcr_inout. 39// 9. assert vcr_set_data, then deassert vcr_set_data. This let next data byte appear on [7:0] vcr_inout. 40// 10. go to step 7 if necessary. 41// 42//*********************************************************** 43 44module vcr( 45 input CS, 46 47 input [7:0] vcr_in, // Vendor Command/Request (VCR) address/data 48 output [7:0] vcr_out, 49 input clk_vcr_addr, // on posedge, set (internal to FPGA) VCR IO address 50 input clk_vcr_data, // on posedge, perform write or synchronous read 51 52 input IFCLK, 53 54 input [2:0] FPGA_ID, 55 input [7:0] hs_io_timeout, 56 input hs_input_prog_full, 57 //input output_err_overflow, 58 input sfifo_not_empty, 59 input io_fsm_error, io_err_write, 60 input [15:0] output_limit, 61 input output_limit_not_done, 62 input progdone_inv, 63 input [7:0] app_status, 64 input [7:0] pkt_comm_status, debug2, debug3, 65 //input [255:0] debug, 66 67 // 68 // Defaults for various controls; see also VCR_RESET 69 // 70 output reg inout_raw = 0, // use PC[7:0] in raw mode 71 output reg hs_en = 0, // enable high-speed i/o 72 output reg output_mode_limit = 1, // output_limit 73 output reg reg_output_limit = 0, // with respect to IFCLK 74 output reg [7:0] app_mode = 0 // default mode: 0 75 ); 76 77 wire ENABLE = CS; 78 79 // VCR address definitions 80 localparam VCR_SET_HS_IO_ENABLE = 8'h80; 81 localparam VCR_SET_HS_IO_DISABLE = 8'h81; 82 localparam VCR_SET_APP_MODE = 8'h82; 83 localparam VCR_GET_IO_STATUS = 8'h84; 84 // registers output limit (in output_limit_fifo words); starts 85 // output of that many via high-speed interface 86 localparam VCR_REG_OUTPUT_LIMIT = 8'h85; 87 localparam VCR_SET_OUTPUT_LIMIT_ENABLE = 8'h86; 88 localparam VCR_SET_OUTPUT_LIMIT_DISABLE = 8'h87; 89 localparam VCR_ECHO_REQUEST = 8'h88; 90 localparam VCR_GET_FPGA_ID = 8'h8A; 91 localparam VCR_RESET = 8'h8B; 92 localparam VCR_GET_ID_DATA = 8'hA1; 93 //localparam VCR_ = 8'h; 94 95 async2sync sync_addr_inst( .async(clk_vcr_addr), .clk(IFCLK), .clk_en(clk_addr_en) ); 96 async2sync sync_data_inst( .async(clk_vcr_data), .clk(IFCLK), .clk_en(clk_data_en) ); 97 98 reg [7:0] vcr_addr; 99 reg [5:0] vcr_state = 0; 100 101 ///////////////////////////////////////////////////////// 102 // 103 // declarations for Command / Request specific stuff 104 // 105 ///////////////////////////////////////////////////////// 106 localparam [15:0] BITSTREAM_TYPE = `BITSTREAM_TYPE; 107 108 reg [7:0] echo_content [3:0]; 109 reg RESET_R = 0; 110 111 // declarations for Command / Request specific stuff end 112 113 114 ///////////////////////////////////////////////////////// 115 // 116 // Input 117 // 118 ///////////////////////////////////////////////////////// 119 120 always @(posedge IFCLK) begin 121 if (ENABLE && clk_addr_en) begin 122 vcr_addr <= vcr_in; 123 vcr_state <= 0; 124 125 if (inout_raw) 126 inout_raw <= 0; 127 else if (vcr_in == 8'h00) 128 inout_raw <= 1; 129 else if (vcr_in == VCR_SET_HS_IO_ENABLE) 130 hs_en <= 1; 131 else if (vcr_in == VCR_SET_HS_IO_DISABLE) 132 hs_en <= 0; 133 else if (vcr_in == VCR_SET_OUTPUT_LIMIT_ENABLE) 134 output_mode_limit <= 1; 135 else if (vcr_in == VCR_SET_OUTPUT_LIMIT_DISABLE) 136 output_mode_limit <= 0; 137 else if (vcr_in == VCR_RESET) 138 RESET_R <= 1; 139 else if (vcr_in == VCR_REG_OUTPUT_LIMIT) 140 reg_output_limit <= 1; 141 142 end // clk_addr_en 143 144 else if (ENABLE && clk_data_en) begin 145 vcr_state <= vcr_state + 1'b1; 146 147 if (vcr_addr == VCR_ECHO_REQUEST) 148 echo_content[ vcr_state[1:0] ] <= vcr_in; 149 else if (vcr_addr == VCR_SET_APP_MODE) 150 app_mode <= vcr_in; 151 end // clk_data_en 152 153 else begin // !ENABLE 154 if (reg_output_limit) 155 reg_output_limit <= 0; 156 157 end 158 end 159 160 161 162 ///////////////////////////////////////////////////////// 163 // 164 // Output 165 // 166 ///////////////////////////////////////////////////////// 167 168 assign vcr_out = 169 (vcr_addr == VCR_REG_OUTPUT_LIMIT && vcr_state == 0) ? output_limit[7:0] : 170 (vcr_addr == VCR_REG_OUTPUT_LIMIT && vcr_state == 1) ? output_limit[15:8] : 171 172 (vcr_addr == VCR_GET_IO_STATUS && vcr_state == 0) ? { 173 progdone_inv, 1'b0, io_err_write, io_fsm_error, 174 sfifo_not_empty, 1'b0, output_limit_not_done, hs_input_prog_full 175 } : 176 (vcr_addr == VCR_GET_IO_STATUS && vcr_state == 1) ? hs_io_timeout : 177 (vcr_addr == VCR_GET_IO_STATUS && vcr_state == 2) ? app_status : 178 (vcr_addr == VCR_GET_IO_STATUS && vcr_state == 3) ? pkt_comm_status : 179 (vcr_addr == VCR_GET_IO_STATUS && vcr_state == 4) ? debug2 : 180 (vcr_addr == VCR_GET_IO_STATUS && vcr_state == 5) ? debug3 : 181 182 (vcr_addr == VCR_ECHO_REQUEST) ? echo_content[ vcr_state[1:0] ] ^ 8'h5A : 183 184 (vcr_addr == VCR_GET_ID_DATA && vcr_state == 0) ? BITSTREAM_TYPE[7:0] : 185 (vcr_addr == VCR_GET_ID_DATA && vcr_state == 1) ? BITSTREAM_TYPE[15:8] : 186 187 (vcr_addr == VCR_GET_FPGA_ID) ? { {5{1'b0}}, FPGA_ID } : 188 //(vcr_addr == && vcr_state == ) ? : 189 8'b0; 190 191 192 startup_spartan6 startup_spartan6(.rst(RESET_R)); 193 194endmodule 195