1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
|
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: Raptor Engineering
// Engineer: Timothy Pearson
//
// Design Name: Remote Access Sample Design
// Module Name: sample_demo
// Project Name: Remote Access Sample Design
// Target Devices: Any
// Description: Remote Access Sample Design
//
// Dependencies:
//
// (c) 2007-2013 Timothy Pearson, Raptor Engineering
// Released into the Public Domain
//
//////////////////////////////////////////////////////////////////////////////////
module main(
input clk, // 100MHz clock
// Serial port
input serial_input,
output serial_output);
parameter RAM_ADDR_BITS = 14;
wire [7:0] four_bit_output; // Output from the user program to the remote access module
wire [7:0] four_bit_input; // Input to the user program from the remote access module
wire [7:0] eight_bit_output; // Output from the user program to the remote access module
wire [7:0] eight_bit_input; // Input to the user program from the remote access module
wire [15:0] sixteen_bit_output; // Output from the user program to the remote access module
wire [15:0] sixteen_bit_input; // Input to the user program from the remote access module
wire [7:0] remote_access_local_input;
reg [7:0] serial_data_to_write;
wire sieze_serial_tx;
reg serial_tx_strobe = 0;
wire serial_data_received;
wire serial_rx_strobe;
wire [5:0] lcd_data_in_address;
wire [7:0] lcd_data_in_data;
wire lcd_data_in_enable;
wire [7:0] led_segment_bus;
wire [3:0] led_digit_select;
//-------------------------------------------------------------------------------------------------------
//
// Generate a 50MHz clock for the remote access module
//
//-------------------------------------------------------------------------------------------------------
reg main_fifty_clock = 0;
always @(posedge clk) begin
main_fifty_clock = !main_fifty_clock;
end
//-------------------------------------------------------------------------------------------------------
//
// Generate a 25MHz clock for the user progam
//
//-------------------------------------------------------------------------------------------------------
reg clk_div_by_two = 0;
always @(posedge main_fifty_clock) begin
clk_div_by_two = !clk_div_by_two;
end
//-------------------------------------------------------------------------------------------------------
//
// Remote Access Module
//
// Inputs:
// .clk: 50MHz clock
// .four_bit_input 4-bit input to the user program from the remote access module
// .eight_bit_input 8-bit input to the user program from the remote access module
// .sixteen_bit_input 16-bit input to the user program from the remote access module
// .serial_port_receiver Input from the serial port's RxD (receive data) pin
// .remote_access_input_enable Toggle remote access input vs. local input mode
// .local_input Local input to the remote program
// .seize_serial_tx Sieze control of the serial transmitter from the remote control system
// .serial_tx_data Byte to be transmitted on transmit strobe if control has been siezed
// .serial_tx_strobe Transmit serial data on posedge if transmit control has been siezed
// .lcd_data_in_address LCD character address (0-32) to write character code to
// .lcd_data_in_data LCD character code to write to the address specified
// .lcd_data_in_enable Enable LCD data write
// .sram_wren_in Synchronous SRAM write enable (1=write, 0=read)
// .sram_clock_in Synchronous SRAM clock input
// .sram_data_in Synchronous SRAM data input (8-bit)
// .sram_address_in Synchronous SRAM address input (14-bit by default)
// .sram_processing_done When 1, signal release of user control of synchronous SRAM
// .led_segment_bus Connect directly to the 8 bits controlling the LED display segments
// .led_digit_select Connect directly to the 4 bits enabling the LED display digits
//
// Outputs:
// .four_bit_output 4-bit output from the user program to the remote access module
// .eight_bit_output 8-bit output from the user program to the remote access module
// .sixteen_bit_output 16-bit output from the user program to the remote access module
// .lcd_data_out Data output to the LCD
// .lcd_rs_out RS signal output to the LCD
// .lcd_rw_out RW signal output to the LCD
// .lcd_enable_out ENABLE signal output to the LCD
// .serial_port_transmitter Output to the serial port's TxD (transmit data) pin
// .serial_rx_data The last received serial data
// .serial_rx_strobe Recevied serial data valid while this signal is 1
// .sram_data_out Synchronous SRAM data output (8-bit)
// .sram_available Synchronous SRAM under user control
//
//-------------------------------------------------------------------------------------------------------
wire sram_wren_in;
wire sram_clock_in;
wire [7:0] sram_data_in;
wire [(RAM_ADDR_BITS-1):0] sram_address_in;
wire [7:0] sram_data_out;
wire sram_available;
wire sram_processing_done;
// Uncomment this block if no image processing module is provided
// assign sram_wren_in = 0;
// assign sram_data_in = 0;
// assign sram_address_in = 0;
// assign sram_processing_done = 1;
assign sram_clock_in = main_fifty_clock;
remote_access #(RAM_ADDR_BITS) remote_access(.main_fifty_clock(main_fifty_clock), .remote_access_4_bit_output(four_bit_output),
.remote_access_4_bit_input(four_bit_input), .remote_access_8_bit_output(eight_bit_output),
.remote_access_8_bit_input(eight_bit_input), .remote_access_16_bit_output(sixteen_bit_output),
.remote_access_16_bit_input(sixteen_bit_input),
.serial_port_receiver(serial_input), .serial_port_transmitter(serial_output), .remote_access_input_enable(btn_center),
.local_input(remote_access_local_input), .seize_serial_tx(sieze_serial_tx), .serial_tx_data(serial_data_to_write),
.serial_tx_strobe(serial_tx_strobe), .serial_rx_data(serial_data_received), .serial_rx_strobe(serial_rx_strobe),
.lcd_data_in_address(lcd_data_in_address), .lcd_data_in_data(lcd_data_in_data), .lcd_data_in_enable(lcd_data_in_enable),
.sram_wren_in(sram_wren_in), .sram_clock_in(sram_clock_in), .sram_data_in(sram_data_in), .sram_address_in(sram_address_in),
.sram_data_out(sram_data_out), .sram_available(sram_available), .sram_processing_done(sram_processing_done),
.led_segment_bus(led_segment_bus), .led_digit_select(led_digit_select));
assign remote_access_local_input[7:4] = 0; // Local inputs
assign remote_access_local_input[3:0] = 0; // Local inputs
assign led_bank = eight_bit_input; // Mirror input to the LEDs
assign sieze_serial_tx = 0; // Allow the remote control module to use the serial port
// If the user module must access the serial port directly, delete
// this assign statement and control this wire with your module.
//-------------------------------------------------------------------------------------------------------
//
// User Module Instantiation
//
// Instantiate the simple user module to display remote access input values on the LEDs and to feed
// button presses to the remote access module. The 16-bit remote access lines are in loopback.
// Feel free to delete this instantiation and the module below to replace it with your module.
//
//-------------------------------------------------------------------------------------------------------
sample_demo sample_demo(.clk(clk_div_by_two), .four_bit_input(four_bit_input), .four_bit_output(four_bit_output),
.eight_bit_input(eight_bit_input), .eight_bit_output(eight_bit_output), .sixteen_bit_input(sixteen_bit_input),
.sixteen_bit_output(sixteen_bit_output), .lcd_data_in_address(lcd_data_in_address),
.lcd_data_in_data(lcd_data_in_data), .lcd_data_in_enable(lcd_data_in_enable),
.led_segment_bus(led_segment_bus), .led_digit_select(led_digit_select));
//-------------------------------------------------------------------------------------------------------
//
// User Image Processing Module Instantiation
//
// Instantiate the simple userimage processing module to invert the bits in any images sent to the FPGA
//
//-------------------------------------------------------------------------------------------------------
sample_image_processing_demo sample_image_processing_demo(.clk(clk_div_by_two), .wren(sram_wren_in), .dout(sram_data_in), .addr(sram_address_in),
.din(sram_data_out), .enable(sram_available), .done(sram_processing_done));
endmodule
//-------------------------------------------------------------------------------------------------------
//
// Demo User Module
//
//-------------------------------------------------------------------------------------------------------
module sample_demo(clk, four_bit_input, four_bit_output, eight_bit_input, eight_bit_output, sixteen_bit_input, sixteen_bit_output, lcd_data_in_address, lcd_data_in_data, lcd_data_in_enable, led_segment_bus, led_digit_select);
input clk;
input [3:0] four_bit_input;
output reg [3:0] four_bit_output;
input [7:0] eight_bit_input;
output reg [7:0] eight_bit_output;
input [15:0] sixteen_bit_input;
output reg [15:0] sixteen_bit_output;
output reg [5:0] lcd_data_in_address;
output reg [7:0] lcd_data_in_data;
output reg lcd_data_in_enable;
output reg [7:0] led_segment_bus;
output reg [3:0] led_digit_select;
reg [7:0] lcd_sample_counter = 48; // Create a sample LCD display counter register
reg [31:0] lcd_character_change_timer = 0; // Wait a certain number of cycles before loading a new character
reg [5:0] lcd_current_character = 0; // The current character's address
always @(posedge clk) begin
four_bit_output = four_bit_input; // Loopback
eight_bit_output = eight_bit_input[3:0] + eight_bit_input[7:4]; // Sample adder
sixteen_bit_output = sixteen_bit_input[15:8] * sixteen_bit_input[7:0]; // Sample multiplier
// Sample LCD display routine
lcd_data_in_address = lcd_current_character; // Character location on the LCD display
lcd_data_in_data = lcd_sample_counter; // Character code to display
lcd_data_in_enable = 1; // Enable data transmission
// Cycle through all character positions
lcd_current_character = lcd_current_character + 1;
if (lcd_current_character > 31) begin
lcd_current_character = 16;
end
// Cycle through the numbers 0 to 9 at one second intervals
lcd_character_change_timer = lcd_character_change_timer + 1;
if (lcd_character_change_timer > 25000000) begin // Wait one second in between character changes
lcd_character_change_timer = 0;
lcd_sample_counter = lcd_sample_counter + 1;
if (lcd_sample_counter > 57) begin // Character code for the digit 9
lcd_sample_counter = 48; // Character code for the digit 0
end
end
end
// 7-segment LED display driver clock generator
reg sseg_clock;
reg [4:0] sseg_clock_counter;
always @(posedge clk) begin
sseg_clock_counter = sseg_clock_counter + 1;
if (sseg_clock_counter > 16) begin
sseg_clock_counter = 0;
sseg_clock = ~sseg_clock;
end
end
// 7-segment LED display driver
// led_segment_bus and led_digit_select are active low
// The bit sequence, MSB to LSB, is dp a b c d e f g
// Segment letters are taken from ug130.pdf page 15
// 0: 8'b10000001
// 1: 8'b11001111
// 2: 8'b10010010
// 3: 8'b10000110
reg [2:0] current_anode;
always @(posedge sseg_clock) begin
current_anode = current_anode + 1;
if (current_anode > 3) begin
current_anode = 0;
end
case (current_anode)
0: begin
led_digit_select = 4'b1110;
led_segment_bus = 8'b10000001;
end
1: begin
led_digit_select = 4'b1101;
led_segment_bus = 8'b11001111;
end
2: begin
led_digit_select = 4'b1011;
led_segment_bus = 8'b10010010;
end
3: begin
led_digit_select = 4'b0111;
led_segment_bus = 8'b10000110;
end
endcase
end
endmodule
//-------------------------------------------------------------------------------------------------------
//
// Demo User Image Processing Module
//
//-------------------------------------------------------------------------------------------------------
module sample_image_processing_demo(clk, wren, dout, addr, din, enable, done);
input clk;
output reg wren;
output reg [7:0] dout;
output reg [(RAM_ADDR_BITS-1):0] addr;
input [7:0] din;
input enable;
output reg done;
reg prev_enable;
reg [(RAM_ADDR_BITS-1):0] counter;
reg toggler;
always @(posedge clk) begin
if ((enable == 1) && (prev_enable == 0)) begin
counter = 0;
toggler = 0;
end
if ((enable == 1) && (done == 0)) begin
if (toggler == 0) begin
wren = 0;
addr = counter;
toggler = 1;
end else begin
dout = ~din;
wren = 1;
addr = counter;
counter = counter + 1;
if (counter > (2**RAM_ADDR_BITS)) begin
done = 1;
end
toggler = 0;
end
end
if (enable == 0) begin
done = 0;
addr = 0;
toggler = 0;
end
prev_enable = enable;
end
endmodule
|