aboutsummaryrefslogtreecommitdiffstats
path: root/examples/icestick/rs232demo.v
diff options
context:
space:
mode:
Diffstat (limited to 'examples/icestick/rs232demo.v')
-rw-r--r--examples/icestick/rs232demo.v124
1 files changed, 116 insertions, 8 deletions
diff --git a/examples/icestick/rs232demo.v b/examples/icestick/rs232demo.v
index 40347e8..9f66f97 100644
--- a/examples/icestick/rs232demo.v
+++ b/examples/icestick/rs232demo.v
@@ -1,17 +1,59 @@
+// A simple design demonstrating receiving and sending of RS232 signals
+//
+// With this design loaded, connect with a serial terminal to the USB serial
+// port of the icestick (with 9600 BAUD) and use the number keys 1..5 to toggle
+// the LEDs.
+
module top (
input clk,
input RX,
output TX,
+ output LED1,
+ output LED2,
+ output LED3,
+ output LED4,
+ output LED5
+);
+ parameter integer BAUD_RATE = 9600;
+ parameter integer CLOCK_FREQ_HZ = 12000000;
+ localparam integer PERIOD = CLOCK_FREQ_HZ / BAUD_RATE;
+
+ rs232_recv #(
+ .HALF_PERIOD(PERIOD / 2)
+ ) recv (
+ .clk (clk ),
+ .RX (RX ),
+ .LED1 (LED1),
+ .LED2 (LED2),
+ .LED3 (LED3),
+ .LED4 (LED4),
+ .LED5 (LED5)
+ );
+
+ rs232_send #(
+ .PERIOD(PERIOD)
+ ) send (
+ .clk (clk ),
+ .TX (TX ),
+ .LED1 (LED1),
+ .LED2 (LED2),
+ .LED3 (LED3),
+ .LED4 (LED4),
+ .LED5 (LED5)
+ );
+endmodule
+
+module rs232_recv #(
+ parameter integer HALF_PERIOD = 5
+) (
+ input clk,
+ input RX,
output reg LED1,
output reg LED2,
output reg LED3,
output reg LED4,
output reg LED5
);
- parameter integer BAUD_RATE = 9600;
- parameter integer CLOCK_FREQ_HZ = 12000000;
- localparam integer HALF_PERIOD = CLOCK_FREQ_HZ / (2 * BAUD_RATE);
-
reg [7:0] buffer;
reg buffer_valid;
@@ -20,11 +62,11 @@ module top (
reg recv = 0;
initial begin
- LED1 = 0;
+ LED1 = 1;
LED2 = 0;
- LED3 = 0;
+ LED3 = 1;
LED4 = 0;
- LED5 = 0;
+ LED5 = 1;
end
always @(posedge clk) begin
@@ -60,6 +102,72 @@ module top (
if (buffer == "5") LED5 <= !LED5;
end
end
+endmodule
+
+module rs232_send #(
+ parameter integer PERIOD = 10
+) (
+ input clk,
+ output TX,
+ input LED1,
+ input LED2,
+ input LED3,
+ input LED4,
+ input LED5
+);
+ reg [7:0] buffer;
+ reg buffer_valid;
+
+ reg [$clog2(PERIOD):0] cycle_cnt = 0;
+ reg [4:0] bit_cnt = 0;
+ reg [5:0] byte_cnt = 60;
+
+ always @(posedge clk) begin
+ cycle_cnt <= cycle_cnt + 1;
+ if (cycle_cnt == PERIOD-1) begin
+ cycle_cnt <= 0;
+ bit_cnt <= bit_cnt + 1;
+ if (bit_cnt == 10) begin
+ bit_cnt <= 0;
+ byte_cnt <= byte_cnt + 1;
+ end
+ end
+ end
+
+ reg [7:0] data_byte;
+ reg data_bit;
+
+ always @* begin
+ data_byte = 'bx;
+ case (byte_cnt)
+ 0: data_byte <= "\r";
+ 1: data_byte <= LED1 ? "*" : "-";
+ 2: data_byte <= LED2 ? "*" : "-";
+ 3: data_byte <= LED3 ? "*" : "-";
+ 4: data_byte <= LED4 ? "*" : "-";
+ 5: data_byte <= LED5 ? "*" : "-";
+ endcase
+ end
+
+ always @(posedge clk) begin
+ data_bit = 'bx;
+ case (bit_cnt)
+ 0: data_bit <= 0; // start bit
+ 1: data_bit <= data_byte[0];
+ 2: data_bit <= data_byte[1];
+ 3: data_bit <= data_byte[2];
+ 4: data_bit <= data_byte[3];
+ 5: data_bit <= data_byte[4];
+ 6: data_bit <= data_byte[5];
+ 7: data_bit <= data_byte[6];
+ 8: data_bit <= data_byte[7];
+ 9: data_bit <= 1; // stop bit
+ 10: data_bit <= 1; // stop bit
+ endcase
+ if (byte_cnt > 5) begin
+ data_bit <= 1;
+ end
+ end
- assign TX = RX;
+ assign TX = data_bit;
endmodule