Skip to content

Commit d561c76

Browse files
committed
Adds basic parsing and data structuring for vhdl and sv doc comments
1 parent 3e992ed commit d561c76

File tree

21 files changed

+1733
-61
lines changed

21 files changed

+1733
-61
lines changed

docs/commands.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,12 +455,14 @@ orbit build --target xsim --force -- --help
455455
# ------------------------------------------------------------------------------
456456
[doc]
457457
name = "doc"
458-
summary = "build a project's documentation"
458+
summary = "generate a project's documentation"
459459
synopsis = "orbit doc [options]"
460460
description = """
461461
Generates a project's documentation from inline markdown comments.
462462
"""
463463

464+
options."--target-dir <dir>" = "Directory for all generated artifacts and intermediate files"
465+
464466
examples = """
465467
orbit doc
466468
"""

docs/src/commands/doc.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## __NAME__
44

5-
doc - build a project's documentation
5+
doc - generate a project's documentation
66

77
## __SYNOPSIS__
88

@@ -14,6 +14,11 @@ orbit doc [options]
1414

1515
Generates a project's documentation from inline markdown comments.
1616

17+
## __OPTIONS__
18+
19+
`--target-dir <dir>`
20+
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Directory for all generated artifacts and intermediate files
21+
1722
## __EXAMPLES__
1823

1924
```

examples/docu/Orbit.lock

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# This file is automatically @generated by Orbit.
2+
# It is not intended for manual editing.
3+
version = 1
4+
5+
[[project]]
6+
name = "docu"
7+
version = "0.1.0"
8+
uuid = "61kfbsth23uk2tgxgwljeo29t"
9+
dependencies = []

examples/docu/Orbit.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[project]
2+
name = "docu"
3+
version = "0.1.0"
4+
uuid = "61kfbsth23uk2tgxgwljeo29t"
5+
ignore = [
6+
"ignore"
7+
]
8+
9+
[dependencies]

examples/docu/foo/.#lock-doc

Whitespace-only changes.

examples/docu/hamm_enc.vhd

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
-- Some random comments
2+
-- are here!
3+
4+
library ieee;
5+
use ieee.std_logic_1164.all;
6+
use ieee.numeric_std.all;
7+
8+
library work;
9+
use work.hamm_pkg.all;
10+
11+
--- Generic hamming-code encoder that takes a message `message` and packages
12+
--- it with corresponding parity bits into an `encoding` for extended
13+
--- hamming code (SECDED).
14+
---
15+
--- Implemented in purely combinational logic. Parity bits are set in the
16+
--- indices corresponding to powers of 2 (0, 1, 2, 4, 8, ...).
17+
entity hamm_enc is
18+
generic (
19+
--- Number of parity bits to encode (excluding 0th DED bit)
20+
PARITY_BITS : positive range 2 to positive'high
21+
);
22+
port (
23+
--- Incoming message
24+
message : in logics(data_size(PARITY_BITS)-1 downto 0);
25+
--- Outgoing encoding
26+
encoding : out logics(block_size(PARITY_BITS)-1 downto 0)
27+
);
28+
end entity hamm_enc;
29+
30+
--- # RTL
31+
--- My basic architecture.
32+
architecture rtl of hamm_enc is
33+
constant EVEN_PARITY : boolean := true;
34+
35+
constant TOTAL_BITS_SIZE : positive := block_size(PARITY_BITS);
36+
constant PARITY_LINE_SIZE : positive := TOTAL_BITS_SIZE/2;
37+
38+
type hamm_block is array (0 to PARITY_BITS-1) of logics(PARITY_LINE_SIZE-1 downto 0);
39+
40+
signal enc_block : hamm_block;
41+
42+
-- +1 parity for the zero-th check bit
43+
signal check_bits : logics(PARITY_BITS-1+1 downto 0);
44+
45+
signal empty_block : logics(TOTAL_BITS_SIZE-1 downto 0);
46+
signal full_block : logics(TOTAL_BITS_SIZE-1 downto 0);
47+
48+
begin
49+
--! Formats the incoming message into a clean hamming-code block with parity
50+
--! bits cleared.
51+
process(message)
52+
variable ctr : natural;
53+
begin
54+
empty_block <= (others => '0');
55+
ctr := 0;
56+
for ii in 0 to TOTAL_BITS_SIZE-1 loop
57+
-- use information bit otherwise reserve for parity bit
58+
if is_pow_2(ii) = false then
59+
empty_block(ii) <= message(ctr);
60+
ctr := ctr + 1;
61+
end if;
62+
end loop;
63+
end process;
64+
65+
--! divide the entire hamming-code block into parity subset groups
66+
process(empty_block)
67+
variable temp_line : logics(PARITY_LINE_SIZE-1 downto 0);
68+
variable index : logics(PARITY_BITS-1 downto 0);
69+
begin
70+
for ii in PARITY_BITS-1 downto 0 loop
71+
temp_line := (others => '0');
72+
for jj in TOTAL_BITS_SIZE-1 downto 0 loop
73+
-- decode the parity bit index
74+
index := (others => '0');
75+
index := logics(to_unsigned(jj, PARITY_BITS));
76+
77+
if index(ii) = '1' then
78+
-- insert new bit
79+
temp_line := temp_line(PARITY_LINE_SIZE-2 downto 0) & empty_block(jj);
80+
end if;
81+
end loop;
82+
-- drive the ii'th vector in the block as this parity's subset of bits
83+
enc_block(ii) <= temp_line;
84+
end loop;
85+
end process;
86+
87+
--! instantiate parity checkers for the subset of bits to evaluate
88+
gen_check_bits: for ii in 0 to PARITY_BITS-1 generate
89+
u_par : entity work.parity
90+
generic map (
91+
SIZE => TOTAL_BITS_SIZE/2,
92+
EVEN_PARITY => EVEN_PARITY
93+
) port map (
94+
data => enc_block(ii),
95+
check_bit => check_bits(ii)
96+
);
97+
end generate gen_check_bits;
98+
99+
--! fill the hamming-code block with computed parity bits
100+
process(empty_block, check_bits)
101+
variable ctr : natural;
102+
begin
103+
full_block <= empty_block;
104+
ctr := 0;
105+
106+
for ii in 1 to TOTAL_BITS_SIZE-1 loop
107+
-- use information bit otherwise reserve for parity bit
108+
if is_pow_2(ii) = true then
109+
full_block(ii) <= check_bits(ctr);
110+
ctr := ctr + 1;
111+
end if;
112+
end loop;
113+
end process;
114+
115+
--! computes the extra parity bit (0th bit) for double-error detection
116+
u_ded : entity work.parity
117+
generic map (
118+
SIZE => TOTAL_BITS_SIZE-1,
119+
EVEN_PARITY => EVEN_PARITY
120+
) port map (
121+
data => full_block(TOTAL_BITS_SIZE-1 downto 1),
122+
check_bit => check_bits(PARITY_BITS)
123+
);
124+
125+
-- drive the output with the hamming-code block and the 0th parity bit
126+
encoding <= full_block(TOTAL_BITS_SIZE-1 downto 1) & check_bits(PARITY_BITS);
127+
128+
end architecture rtl;

examples/docu/hamm_pkg.vhd

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
--------------------------------------------------------------------------------
2+
--! Project : Hamming
3+
--! Engineer : Chase Ruskin
4+
--! Created : 2022-10-10
5+
--! Entity : hamm_pkg
6+
--! Details :
7+
--! Hamming code package consisting of helper functions and constants.
8+
--------------------------------------------------------------------------------
9+
library ieee;
10+
use ieee.std_logic_1164.all;
11+
use ieee.numeric_std.all;
12+
13+
--- Hamming code package consisting of helper functions.
14+
package hamm_pkg is
15+
16+
subtype logic is std_ulogic;
17+
subtype logics is std_ulogic_vector;
18+
19+
--- Determines if the `num` is a power of 2.
20+
---
21+
--- Includes values of 0 and 1.
22+
function is_pow_2(num: natural) return boolean;
23+
24+
--- Computes the number of data bits for a hamming-code block.
25+
function data_size(parity_bits: positive range 2 to positive'high) return positive;
26+
27+
--- Computes the number of bits in the entire hamming-code block.
28+
function block_size(parity_bits: positive range 2 to positive'high) return positive;
29+
30+
end package hamm_pkg;
31+
32+
33+
package body hamm_pkg is
34+
35+
function is_pow_2(num: natural) return boolean is
36+
variable temp: natural;
37+
begin
38+
temp := num;
39+
while temp > 2 loop
40+
if temp rem 2 /= 0 and temp > 2 then
41+
return false;
42+
end if;
43+
temp := temp / 2;
44+
end loop;
45+
return true;
46+
end function;
47+
48+
function data_size(parity_bits: positive range 2 to positive'high) return positive is
49+
begin
50+
return (2**parity_bits)-parity_bits-1;
51+
end function;
52+
53+
function block_size(parity_bits: positive range 2 to positive'high) return positive is
54+
begin
55+
return 2**parity_bits;
56+
end function;
57+
58+
end package body;

examples/docu/ignore/bcd_enc.sv

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
module bcd_enc #(
2+
parameter int LEN = 4,
3+
parameter int DIGITS = 2
4+
) (
5+
input logic rst,
6+
input logic clk,
7+
input logic go,
8+
input logic[LEN-1:0] bin,
9+
output logic[(4*DIGITS)-1:0] bcd,
10+
output logic done,
11+
output logic ovfl
12+
);
13+
14+
typedef enum {S_WAIT, S_SHIFT, S_ADD} state;
15+
16+
logic[$bits(bcd)+$bits(bin)-1:0] dabble_r, dabble_d;
17+
18+
logic ovfl_r, ovfl_d;
19+
state state_r, state_d;
20+
logic done_r, done_d;
21+
22+
localparam int CTR_LEN = $clog2(LEN);
23+
24+
logic[CTR_LEN-1:0] ctr_r, ctr_d;
25+
26+
// registers with positive async reset
27+
always_ff @(posedge rst, posedge clk) begin
28+
if(rst == 1'b1) begin
29+
ovfl_r <= '0;
30+
dabble_r <= '0;
31+
ctr_r <= '0;
32+
done_r <= '0;
33+
state_r <= S_WAIT;
34+
end else begin
35+
state_r <= state_d;
36+
ctr_r <= ctr_d;
37+
done_r <= done_d;
38+
ovfl_r <= ovfl_d;
39+
dabble_r <= dabble_d;
40+
end
41+
end
42+
43+
// simple pass through
44+
assign ovfl = ovfl_r;
45+
assign done = done_r;
46+
assign bcd = dabble_r[LEN +: $bits(bcd)];
47+
48+
// determine next state and output signals
49+
always_comb begin
50+
logic[3:0] bcd_digit;
51+
52+
state_d = state_r;
53+
ctr_d = ctr_r;
54+
ovfl_d = ovfl_r;
55+
dabble_d = dabble_r;
56+
done_d = done_r;
57+
58+
case(state_r)
59+
// Wait to capture inputs on the start of a request
60+
S_WAIT: begin
61+
if(go == 1'b1) begin
62+
dabble_d = '0;
63+
dabble_d[$bits(bin)-1:0] = bin;
64+
ctr_d = '0;
65+
ovfl_d = '0;
66+
state_d = S_SHIFT;
67+
done_d = '0;
68+
end
69+
end
70+
// perform the "double" (multiply by 2)
71+
S_SHIFT: begin
72+
dabble_d = dabble_r << 1;
73+
ovfl_d = ovfl_r | dabble_r[$bits(dabble_r)-1];
74+
ctr_d = ctr_r + 1;
75+
if(ctr_r == (CTR_LEN)'(LEN-1)) begin
76+
state_d = S_WAIT;
77+
done_d = 1'b1;
78+
end else begin
79+
state_d = S_ADD;
80+
end
81+
end
82+
// perform the "dabble" (+3 when >= 5)
83+
S_ADD: begin
84+
for(int i = DIGITS-1; i >= 0; i--) begin
85+
bcd_digit = dabble_r[(4*i)+LEN +: 4];
86+
if(bcd_digit >= 5) begin
87+
dabble_d[(4*i)+LEN +: 4] = bcd_digit + 3;
88+
end
89+
end
90+
state_d = S_SHIFT;
91+
end
92+
default: begin
93+
state_d = S_WAIT;
94+
end
95+
endcase
96+
end
97+
98+
endmodule

0 commit comments

Comments
 (0)