summaryrefslogtreecommitdiffstats
path: root/top.v
blob: c5bbd5e95a65a695b697a1ba2a91f152a63b65b0 (plain)
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
/*
 * Top module for iCEstick UART
 * Blinks all LEDs and transmits a holy message over UART.
 * License: GPLv3
 */

module top(input hwclk, output LED1, output LED2, output LED3, output LED4, output LED5, output ftdi_tx);
	/* ~9600Hz clock (12MHz source clock) */
	reg clk_9600 = 0;
	reg [31:0] cntr_9600 = 32'b0;
	parameter period_9600 = 625;

	/* ~1Hz clock (12MHz source clock) */
	reg clk_1 = 0;
	reg [31:0] cntr_1 = 32'b0;
	parameter period_1 = 6000000;

	/* Buffer for byte to send over UART */
	reg [7:0] uart_txbyte = "I";
	/* Send data rather than idle */
	reg uart_send = 1'b1;
	/* Set to 1 after byte transmission is complete */
	wire uart_txed;

	/* UART transmitter module - 8 bits, no parity, 1 stop bit
				9600 baud	byte to be transmitted	send on baud clock	output: tx completed	output: UART tx pin */
	uart_tx_8n1 transmitter(.clk(clk_9600), .txbyte(uart_txbyte), .senddata(uart_send), .txcomplete(uart_txed), .tx(ftdi_tx));

	/* LED register */
	reg ledval = 0;
	/* Assign ledval to all LEDs */
	assign LED1 = ledval;
	assign LED2 = ledval;
	assign LED3 = ledval;
	assign LED4 = ledval;
	assign LED5 = ledval;

	/* Reduced clock generator */
	always @ (posedge hwclk) begin
		/* ~9600Hz clock */
		cntr_9600 <= cntr_9600 + 1;
		if (cntr_9600 == period_9600) begin
			clk_9600 <= ~clk_9600;
			cntr_9600 <= 32'b0;
		end

		/* ~1Hz clock */
		cntr_1 <= cntr_1 + 1;
		if (cntr_1 == period_1) begin
			clk_1 <= ~clk_1;
			cntr_1 <= 32'b0;
		end
	end

	/* Blink all LED's at ~1s interval */
	always @ (posedge clk_1) ledval <= ~ledval;

	/* 4 bits - counts 0-15. As the first char ("I") is already declared and will be transmitted, count is default 1 */
	reg [3:0] count = 4'd1;

	always @ (posedge clk_9600) begin
		/* Set the byte to transmit after last byte has been transmitted */
		if (uart_txed == 1) begin
			/* Holy message needs to be in little endian order - bitshift selects 1 character at a time */
			uart_txbyte <= "\n\rootneG llatsnI" >> count*8;
			//uart_txbyte <= 8'("\n\rootneG llatsnI" >> count*8); //Fully correct, but static casting needs systemverilog support - implicit casting still works fine
			count <= count + 1;
		end
	end

endmodule