summaryrefslogtreecommitdiff
path: root/playground/par_to_ser.v
diff options
context:
space:
mode:
Diffstat (limited to 'playground/par_to_ser.v')
-rw-r--r--playground/par_to_ser.v64
1 files changed, 64 insertions, 0 deletions
diff --git a/playground/par_to_ser.v b/playground/par_to_ser.v
new file mode 100644
index 0000000..ab754c9
--- /dev/null
+++ b/playground/par_to_ser.v
@@ -0,0 +1,64 @@
+`timescale 1us/1us
+
+// parallel to serial converter
+
+module par_to_ser #(
+ parameter SHIFT_WIDTH = 8
+) (
+ input rst_i,
+ input clk_i,
+ input data_valid_i,
+ input [(SHIFT_WIDTH-1):0] dat_i,
+ output reg dat_o,
+ output dat_valid_o
+);
+
+// Learning: can't declate parameter here
+// if I want to use it in the input/output list.
+// parameter SHIFT_WIDTH = 8;
+
+reg [(SHIFT_WIDTH-1):0] send_data = {SHIFT_WIDTH{1'b1}};
+// want to count to number *including* width, add 1
+reg [$clog2(SHIFT_WIDTH + 1) - 1:0] count = 0;
+
+// yes, smaller than, the count *to* 8 still takes place
+wire counting = (count != 0) && (count < SHIFT_WIDTH);
+// sending is one byte longer
+wire sending = (count != 0) && (count <= SHIFT_WIDTH);
+
+always @(posedge clk_i or negedge rst_i) begin
+ if (!rst_i) begin
+ dat_o <= 1'b1;
+ end else if (data_valid_i && count == 0) begin
+ dat_o <= dat_i[0];
+ end else if (sending) begin
+ dat_o <= send_data[0];
+ end
+end
+
+always @(posedge clk_i or negedge rst_i) begin
+ if (!rst_i) begin
+ send_data <= {SHIFT_WIDTH{1'b1}};
+ end else if (data_valid_i && count == 0) begin
+ send_data <= {1'b1, dat_i[(SHIFT_WIDTH-1):1]};
+ end else if (sending) begin
+ // arbitrary decision: register is filled with a 1
+ send_data <= {1'b1, send_data[(SHIFT_WIDTH-1):1]};
+ end
+end
+
+always @(posedge clk_i or negedge rst_i) begin
+ if (!rst_i) begin
+ count <= 0;
+ end else if (data_valid_i && count == 0) begin
+ count <= 1;
+ end else if (counting) begin
+ count <= count + 1;
+ end else begin
+ count <= 0;
+ end
+end
+
+assign dat_valid_o = sending;
+
+endmodule