summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--par_to_ser.tb.v8
-rw-r--r--par_to_ser.v63
2 files changed, 48 insertions, 23 deletions
diff --git a/par_to_ser.tb.v b/par_to_ser.tb.v
index 2d1fc6d..f80042b 100644
--- a/par_to_ser.tb.v
+++ b/par_to_ser.tb.v
@@ -33,19 +33,17 @@ always #10 clk_i = ~clk_i;
initial begin
#37
- dat_i <= 8'b00110011;
+ dat_i <= 8'b00110010;
#13
data_valid_i <= 1'b1;
// clock data in
#20
- // wait 8 clock cycles?
- #160
-
+ // let module do its work
data_valid_i <= 1'b0;
- #400
+ #500
$finish();
end
diff --git a/par_to_ser.v b/par_to_ser.v
index 6b2e375..c4fb13b 100644
--- a/par_to_ser.v
+++ b/par_to_ser.v
@@ -1,40 +1,67 @@
// parallel to serial converter
-module par_to_ser (
+module par_to_ser #(
+ SHIFT_WIDTH = 8
+) (
input rst_i,
input clk_i,
input data_valid_i,
- input [7:0] dat_i,
+ input [(SHIFT_WIDTH-1):0] dat_i,
output reg dat_o
);
+//parameter SHIFT_WIDTH = 8;
-reg sending = 1'b0;
+// reg sending = 1'b0;
reg [7:0] send_data = 8'hff;
-
-// Learning:
-// Ugh, this is fucking stupid.
-// if I send out directly at the rising clock edge,
-// the output, when directly used again with the same clock,
-// will violate setup and hold times???
-//
+// want to count to number *including* width, add 1
+reg [$clog2(SHIFT_WIDTH + 1) - 1:0] count = 0;
+reg sending = 1'b0;
always @(posedge clk_i or negedge rst_i) begin
if (!rst_i) begin
- dat_o <= 1'b1;
sending <= 1'b0;
- send_data <= 8'hff;
- end else if (data_valid_i && !sending) begin
+ end else if (data_valid_i && count == 0) begin
sending <= 1;
- dat_o <= dat_i[0];
- send_data <= {1'b1, dat_i[7:1]};
- end else if (!data_valid_i) begin
- sending <= 1'b0;
+ end else if (count == SHIFT_WIDTH) begin
+ sending <= 0;
+ end
+end
+
+always @(posedge clk_i or negedge rst_i) begin
+ if (!rst_i) begin
dat_o <= 1'b1;
- end else if (sending) begin
+ 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 <= 8'hff;
+ end else if (data_valid_i && count == 0) begin
+ send_data <= {1'b1, dat_i[7:1]};
+ end
+ else if (sending) begin
// arbitrary decision: register is filled with a 1
send_data <= {1'b1, send_data[7: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
+ // yes, smaller, the count *to* 8 still takes place
+ else if (sending && count < SHIFT_WIDTH) begin
+ count <= count + 1;
+ end else begin
+ count <= 0;
+ end
+end
+
endmodule