summaryrefslogtreecommitdiff
path: root/par_to_ser.v
blob: 8c814c4cb394771abaeef748b8bc304c820f3aa5 (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
// 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
);

// 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

endmodule