Commit c2a427ea authored by egousiou's avatar egousiou

Code review: comments on the comments (but still not everything finished)

git-svn-id: http://svn.ohwr.org/cern-fip/trunk/hdl/design@171 7f0067c9-7624-46c7-bd39-3fb5400c0213
parent ad26318d
General comments:
----------------
I don't agree with Matthieu's and Tom's comments about entities ports.
I don't know if you have a guideline on this, but in my case I prefer having
inputs all together and outputs all together, then maybe organized by interface
but only within the inputs or the within the outputs.
wf_cons_frame_validator.vhd
---------------------------
Line 173: why does s_cons_lgth_byte_ok depend on rx_fss_crc_fes_manch_ok_p_i?
In any case the output cons_frame_ok_p_o will only be valid when
rx_fss_crc_fec_manch_ok_p_i is valid.
In my opinion s_cons_lgth_byte_ok should not be forced to 0 because there
is (for example) an error on the crc. When debugging a simulation it is easy
assume that if s_cons_lgth_byte_ok is 0, it's only because the length was wrong.
In fact as the file is written now, the AND between rx_fss_crc_fes_manch_ok_p_i
and s_cons_lgth_byte_ok on lines 205 and 206 is redundant with the
"if then else" of the lines 173, 185 and 187.
---> bug corrected! input rx_crc_or_manch_wrong_p_i added and the Length byte
is checked if either rx_fss_crc_fec_manch_ok_p_i OR rx_crc_or_manch_wrong_p_i
(the output of this OR signals the end of a frame) is activated
wf_cons_bytes_processor.vhd
---------------------------
Line 191: the comment could be re-phrased to
PORT A: connected to Wishbone interface for reading by the user.
PORT B: used by nanoFIP memory to write into memory.
---> OK!
Line 267: s_base_addr is an input and an output of the combinatorial process.
Synplify should give a "combinatorial loop" warning about this.
This line could be written as a separate process.
---> s_base_addr is out of the process, as a concurrent statement
Lines 290 to 294: the comment is not very clear. Is this to avoid writing
the CRC in the memory?
---> Yes! Extra comment added.
In general for this module, the only reason to have the RAM block memory - and
therefore the Wishbone interface signals wb_clk_i, wb_adr_i and data_o -
instantiated in this entity is to be able to integrate the multiplexor of lines
226 and 227.
In my opinion it would much clearer for the general structure, and for the
functionality of this particular block, to take out the memory and instantiate
it in an independent block along with the multiplexor for data_o.
---> I think i will not follow that:-s
wf_engine_control.vhd
---------------------
Line 377-380: What happens if 2 consecutive ID_DAT arrive within the silence time.
The second one will not be processed correctly since it will be treated as an
RP_DAT and therefore discarded because of wrong CTRL byte. But if the second was
a correct ID_DAT, nanoFIP should interpret it correctly.
---> ..........................................................................
Line 775:
One signal is assigned in statements that are not mutually exclusive.
Is this process going to be synthesized the same way by all the tools?
Inside the FOR loop there is an IF-THEN without an ELSE.
Does it generate a latch?
Is the construction with FOR and EXIT statement necessary?
Line 817: The same as above
---> Processes for the var identification rewritten!
wf_rx_tx_osc.vhd
----------------
wf_rx_deserializer.vhd
----------------------
I am not sure if in case a frame is received with one bit missing inside the
data, but with a CRC that is correct with respect to the bits actually
received, the frame would effectively be discarded as it should.
(As responsible for the testbench, I take note that I should check that :-)
---> bug corrected! The FES_detected_p pulse is combined with the byte_ready_p pulse,
that arrives only after the reception of 8 bits.
nanofip.vhd
-----------
Line 480: Coherency in signal names (the _p, or the _rx_)
Line 474: the same....
---> OK!
Comments on NanoFIP VHDL code from Javier Serrano
General comments
----------------
The code is very clear and the abundance of comments makes it easy to
follow. Some signal names are way too long though. It would be more
useful in general to give some good comments about the meaning of
signals next to their declaration, instead of trying to embed too much
info in the signal name.
The guidelines specify that active low signals should be suffixed with
_n. Sometimes we see signals or ports were the underscore has been ommitted,
like rstpon_i, which make it difficult to figure out if the n if part
of the name ("power oN reset") or if it is there to mark the signal as
active low (which in this particular case it is).
---> signals of nanoFIP's pinout couldn't be changed:-s
corrections applied to the rest!
If a file is not listed below it does not mean all is good, just that
I did not have time to look at it ;)
Question for Eva (did not have time to look): we know all inputs are
well registered. Are all outputs registered as well?
---> Yes!
nanofip.vhd
-----------
Line 313 and 314. Synplify attributes make code less portable. Could
they be pushed out of the code into some Synplify config file? I don't
have strong feelings about this though.
---> OK!
wf_engine_control.vhd
---------------------
Line 198. It is preferable to have all ports be std_logic or
std_logic_vector, see comment on line 178 of the reset unit.
---> Pablo: "Using std_logic on entity ports is a strong rule in cores.
As wf_engine_control.vhd is interfaced with other custom entities
this rule should become only a recomendation. Passing var as a custom
type gives the possibility to the designer to chose the suitible encoding
scheme easily wich is very handy for this critical signal."
Line 290. This state machine can be stuck in a given state for a
number of reasons, most notably the physical interruption of the wfip
traffic. Granted, things should go back to normal (i.e. Idle) once the
link is re-established, thanks to the appearance of rx_byte_ready_p_i
pulses with incoherent byte contents, but that's a bit weak in terms
of protection. I would favor timeouts relying only on the system clock
as an additional way to go back to Idle. In fact this is probably a
comment that applies to other state machines in the design. The
"finger-crossing" nature of the current protection is even more
apparent in the id_dat_frame_ok state, where after a link cut you have
to wait until a valid received frame while the counter (free running)
is more than 2 in value. Again, not a high risk for things to go
wrong, but we can get quite a lot of peace of mind with independent
timeouts. After a bit of thinking, something worse could happen: the
state machine could be stopped in the id_dat_frame_ok state and
re-awakened after a while (when the link is back) and then go to
consumption of some dummy data that was not even destined to this
station. IMHO independent timeouts should be mandatory in all states
of all state machines bound to have this type of problems, unless the
cost in logic is prohibitive.
---> OK! Timeouts relying only on system clock applied to all state machines.
wf_incr_counter.vhd
-------------------
Line 72. The ports nfip_rst_i and reinit_counter_i do exactly the same
thing. One should go. Also, the counter does not know it's inside a
nanofip, I think a reset should be called rst_i and not nfip_rst_i.
---> OK! nfip_rst_i removed.
Line 81. Minor point. The output port counter_o should be
std_logic_vector. See similar comment for line 178 of
wf_reset_unit.vhd.
---> I think i won't follow this one:-s; the output of the counter is usually
used for further calculations+making it a std_logic_vector would mean
applying several conversions.
wf_inputs_synchronizer.vhd
--------------------------
Line 240. These two signals are very critical: the fd_rxd_edge_p_o
output is made from them. And then this edge detection signal is fed
to the wf_rx_tx_osc block, where it is used to manufacture very
critical "clock" signals whose malfunctioning would compromise the
deglitcher block. It is therefore important to try to have these edge
detectors as robust as possible, and add deglitching here. With the
current implementation if there is a glitch in the rx line, even
narrower than one uclk period, there is a risk of generating a
spurious edge pulse. Making something much more robust is easy and
cheap: add four more stages to the pipeline (for a total of six usable
signals) and do a super-robust edge detector by requiring that at
least two signals are zero (out of the first three) and at least two
are one (out of the last three). Viceversa of course for detecting the
other edge. For extra-robustness, inhibit detection for a while after
a detected edge. This will induce a delay, which might have to be
compensated in other signals (fd_rxd_o) so the whole thing is
coherent.
---> OK! New deglitcher at the entrance of FD_RXD.
Line 250 onwards. Cosmetics: the vector notation is shorter, so I'd
stick to it for all cases, including the varX_access.
---> OK!
Line 326. I don't think it's a good idea to synchronize the data from
the user in slone mode. If there is an incoherent state (i.e. some
bits have flipped and others haven't) this state will propagate
through the pipeline. Only control signals need to be synchronized (as
is done for the wishbone). The user *must* ensure the data are stable
by the time VAR3_RDY goes to zero, so the 3*16 FFs spent here can only
get us trouble. Incidentally, I think we should change the spec so it
does not say we sample the data on the first clock tick after VAR3_RDY
goes down. We can also sample a couple of ticks later, the user should
not care.
---> OK! No synchronization buffers for DAT_I.
Oops, now I see these lines are also used in wishbone mode
for data_in. I am pretty sure the argument still applies. In fact we
are not synchronizing the WB address, why synchronize the data_in?
---> JFTR these lines were only used for the slone operation; in memory mode
only the control signals were synched (neither the address nor the data)
Line 347. One could argue about the need for these. We know these
inputs are static. While I can't really think how these FFs could get
us in trouble, they are certainly not needed, so why risk it?
---> OK! Removed synch of constant signals.
wf_reset_unit.vhd
-----------------
Line 178. Minor point. It is better to use only std_logic and
std_logic_vector for ports, for the reasons explained in paragraph
4.15 in the guidelines. This is most important for the top entity, so
not very important here. Internal conversion to t_var should be
simple.
Line 419. Minor detail. "reception or" -> "reception of"
Line 421. Same thing.
---> OK!
wf_rx_deglitcher.vhd
--------------------
Line 90. Minor point. It should be "g_DEGLITCH_LGTH" instead of
"c_DEGLITCH_LGTH".
---> OK!
Line 103. Minor: it should be "WF_rx_tx_osc" instead of "WF_tx_rx_osc".
---> OK!
wf_rx_deserializer.vhd (only looked at part of it)
----------------------
Line 240. I wonder if we should have an additional condition which
takes this state machine to Idle, namely the wfip link being inactive,
i.e. maintaining a constant level for a long (to be defined)
time. This would ensure the state machine is always sitting in the
Idle state before the beginning of a frame. With the current
implementation, it might well be the case, but there are many
scenarios to analyze and we risk forgetting something.
--->................................................................
wf_rx_tx_osc.vhd
----------------
Line 106. Minor point. Generics should start with "g_".
---> OK!
Comments on NanoFIP VHDL code from Matthieu Cattin
general comments
--------------------------------------------------------------------------------
* Entities inputs and outputs grouping -> group by interface.
---> I think i won't follow this one:-s (prefer 1st grouping by direction and
then by interface)
* Several signal declaration per line.
* According to coding guidelines generics shoud be named g_MY_GENERIC
and constants c_MY_CONSTANT.
---> OK! clarified generics and package constants.
* The coding style is not consistant.
---> ??..Corrected some inconsistencies:-s
* Synplify warnings in the code. Why?
---> OK! Removed
* In the comments, the following figure:
_
__| |__
is perhaps clearer than:
__|-|__
The line in the middle can be taken for a high impedance state.
==> BAD IDEA, it takes 2 lines.
---> Bad idea!
* Use @details for big descriptions and @brief just for a summary.
---> The details in the @details are the dependencies, modified by, etc
* To clean file layout, in emacs you could use C-c C-b and M-x delete-trailing-whitespace
---> OK! Trailing whitespaces deleted; the beautifier though changes many other things
(arrows alignment, comments location etc) that i prefer in my way:-s
* Remove todo list from files header.
---> OK! (finished with the 'do's)
WF_package.vhd
--------------------------------------------------------------------------------
Lines 220->227. Turnaround and silence constants don't corresponds to the
functional spec!
---> specs updated version
Line 239. What is var_whatever used for?
---> makes simulation debugging clearer
nanofip.vhd
--------------------------------------------------------------------------------
Lines 313, 314. Avoid synthesizer specific attibute inside source code.
You can probably use a constraint file.
---> OK!
WF_inputs_synchronizer.vhd
--------------------------------------------------------------------------------
All file. Sometimes signals are synchronized like that:
s_slone_d3 <= s_slone_d3 (1 downto 0) & slone_a_i;
And sometime like this:
s_var1_access_d1 <= var1_access_a_i;
s_var1_access_d2 <= s_var1_access_d1;
s_var1_access_d3 <= s_var1_access_d2;
The result is the same, but why two coding style then?
---> OK! only vector notation used
Line 238. The comment "to clean rxd from txd" is not clear for me.
Lines 60->62. What do you mean by;
"in nanoFIP input fd_rxd we also see the nanoFIP output fd_txd"
Is it due to cross-talk?
Or is it a normal behaviour of the FieldDrive?
---> It is the normal behaviour of the FIELDRIVE!
However, finally the signal FD_RXCDN is not used at all in order to make
nanoFIP compatible with any other tranceiver.
Lines 72->76. I would commit the Synplify report (and all other reports)
to the SVN and remove this comment.
---> OK!
wf_reset_unit.vhd
--------------------------------------------------------------------------------
Line 83. assert_RSTON should be replaced by assert_RSTON_p
---> OK!
Lines 269, 435. Use of s_por (asynchronous) in a synchronous process!
---> Was not a completed processs (mentioned in the todo list)!
Now the falling edge of RSTPON is synched with the uclk and the wb_clk.
Line 408. Assignment of s_counter_full is far from here.
Consider removing the signal s_counter_full.
---> OK!
Lines 419, 421, 424. Typo "If after the reception or a var_rst [..]".
Should be "If after the reception OF a var_rst [..]".
---> OK!
Line 460. Just in case of what?
---> Removed! (was just in case..i had not done the check of var_i before:-s)
Line 484. An the winner of the biggest variable name is ....
---> Reduced!
Line 629. Assignment of s_var_rst_counter_full is really far from here.
Consider removing the signal s_var_rst_counter_full.
---> OK!
wf_incr_counter.vhd
--------------------------------------------------------------------------------
Line 81. All entity port must be std_logic or std_logic_vector.
Line 109. nfip_rst_i is equal to reinit_counter_i.
---> OK! nfip_rst_i removed
wf_rx_tx_osc.vhd
--------------------------------------------------------------------------------
Line 28. Typo "Generation the clock signals needed [..]".
Should be "Generation OF the clock signals needed [..]".
---> OK!
Lines 49->53. This figure is not clear to me.
---> OK! small clearification added
Lines 106, 114. Inconsistent generic names. _LENGTH and _LGTH
---> OK! only LGTH used
Line 187. Not clear "# uclock ticks for a period".
Should be "# uclock ticks for a bit period".
Or "# uclock ticks for a manchester bit period".
---> OK! Is "# uclock ticks for a bit period".
Line 189. Divide by 2 would be a more useful comment ;)
Line 190. Divide by 4 ...
---> OK! (..but the names are half_period, one_forth_period:-pp)
Line 191. Is s_jitter a good name for this signal?
---> OK! renamed to s_margin.
#################### IMPORTANT ####################
Line 252. When the first falling edge arrives (or the following significant edges)
s_rx_counter is reset and start counting.
And the significant edge window is valid as long as s_rx_counter is
smaller than s_jitter.
It means that just after an edge if another comes before
s_rx_counter = s_jitter, the edge is valid.
There is probalby something wrong here.
#################### IMPORTANT ####################
---> Bug corrected; if 1 edge is found in the window, no other edge is considered
within it (check "s_signif_edge_found=1" added)
wf_consumption.vhd
--------------------------------------------------------------------------------
Line 266. Not useful to put the generic map, the default value is also 10.
---> OK!
Line 301. sample_manch_bit_p_i can be connected directly to sample_manch_bit_p_i
without going through wf_rx_deglitcher, which is just forwarding
sample_manch_bit_p_i to sample_manch_bit_p_o. -> more readable.
Line 294. Same remark as for sample_manch_bit_p_i.
---> OK!
wf_rx_deglitcher.vhd
--------------------------------------------------------------------------------
Line 90. What is the unit of the deglitch length?
That whould be nice to add a comment.
---> deglitcher changed
Lines 112, 113. These two ports can be removed, see wf_consumption.vhd comments
Line 294 and 301.
---> OK!
Line 176. There is a TAB at the begining of the line.
---> OK!
Line 177. Nice trick!
wf_rx_deserializer.vhd
--------------------------------------------------------------------------------
Line 374. Ouputs of the FSM are ~= to the FSM state.
FSM states could be used in other processes, this would make the code
easier to read.
---> I think i won't follow this one:-s
#################### IMPORTANT ####################
Line 323. The only way to get out of switch_to_deglitched is to receive a
filtered falling edge. What append if you don't?
-> A reset is needed.
All other states can return to IDLE, but not this one!
#################### IMPORTANT ####################
---> OK! state removed (deglitcher changed) and general timeout relying only on
the system clock added.
Line 474. s_write_bit_to_byte is a pulse -> add _p
---> OK!
Line 586. Instance value same as default value.
---> OK!
Line 631. You say "that doesn't belong to the FES" but in the if there is
s_fes_wrong_bit = '1'. So either the comment or the test is wrong.
---> I think it is all correct! If s_fes_wrong_bit=1, the bit does not
belong to the FES
Line 692. (not s_manch_not_ok) = manchester ok, which is probalby not what you want.
---> Bug corrected!
wf_cons_bytes_processor.vhd
--------------------------------------------------------------------------------
Line 95. Still some stuff to do...
Line 292. two can be replaced by 2 as you're dealing with unsigned.
---> OK!
Line 392. Here is the var_whatever!
WF_DualClkRAM_clka_rd_clkb_wr.vhd
--------------------------------------------------------------------------------
No comment.
DualClkRAM.vhd
--------------------------------------------------------------------------------
You should mention that this entity is vendor/component specific.
---> OK!
WF_cons_bytes_to_dato.vhd
--------------------------------------------------------------------------------
Lines 136, 143. how could "it" stays there if the signal in the test is a pulse?
---> There is no "else" in the "if"
WF_engine_control.vhd
--------------------------------------------------------------------------------
Line 640. This should be the FSM outputs.
---> I think i won't follow this one:-s
Lines 827, 829. Use constants instead of "01" and "10", it will be more readable.
---> I think i won't follow this one:-s
WF_prod_data_lgth_calc.vhd
--------------------------------------------------------------------------------
Line 110. You should only use std_logic and std_logic_vector for entity ports.
Lines 177->194. if/end if missaligned.
---> OK!
Line 198. Same as line 201.
WF_cons_frame_validator.vhd
--------------------------------------------------------------------------------
Line 112. You should only use std_logic and std_logic_vector for entity ports.
WF_cons_outcome.vhd
--------------------------------------------------------------------------------
Line 106. You should only use std_logic and std_logic_vector for entity ports.
WF_production.vhd
--------------------------------------------------------------------------------
Line
WF_prod_permit.vhd
--------------------------------------------------------------------------------
Line 89. You should only use std_logic and std_logic_vector for entity ports.
WF_prod_bytes_retriever.vhd
--------------------------------------------------------------------------------
Line 169. You should only use std_logic and std_logic_vector for entity ports.
Line 234. (8 downto 0) is useless here.
---> OK!
Line 419. Same as line 427.
WF_prod_bytes_from_dati.vhd
--------------------------------------------------------------------------------
No comment.
WF_status_bytes_gen.vhd
--------------------------------------------------------------------------------
Line 303. Once there is a fieldrive transmission error, the status bit stays at
one. Is that what you want?
Line 310. Same as for line 303.
---> Yes!
WF_tx_serializer.vhd
--------------------------------------------------------------------------------
Line 94. Yes ;)
WF_bits_to_txd.vhd
--------------------------------------------------------------------------------
Line 103 You should only use std_logic and std_logic_vector for entity ports.
WF_manch_encoder.vhd
--------------------------------------------------------------------------------
No comment.
WF_model_constr_decoder.vhd
--------------------------------------------------------------------------------
No comment.
WF_wb_controller.vhd
--------------------------------------------------------------------------------
Lines 122, 135. Why is the address used to generate the ack?
---> The address is essential for both a read and a write ACK.
WF_inputs_synchronizer.vhd
Considering radiation hardness registering constant inputs on three flip flops stages is probably a weekness. Proabably only one TMR flip-flop per input would be enough.
---> Corrected! Removed the 3ple registration for the constant inputs; only TMR.
The wishbone bus is actually properly implemented as it removes any flip-flops from the data and address bus. Notice that the traditional synchronous implementation would require to register the data and address on the IOs, preventing the use of TMR flip-flops.
I made a synthesis with XST on an Spartan6. No serious problems. It only found the following warnings:
WARNING:HDLCompiler:92 - "E:\ohr\cern-fip\trunk\hdl\design\wf_crc.vhd" Line 184: s_q_check_mask should be on the sensitivity list of the process
WARNING:HDLCompiler:1127 - "E:\ohr\cern-fip\trunk\hdl\design\wf_DualClkRAM_clka_rd_clkb_wr.vhd" Line 122: Assignment to zero ignored, since the identifier is never used
WARNING:HDLCompiler:1127 - "E:\ohr\cern-fip\trunk\hdl\design\wf_bits_to_txd.vhd" Line 165: Assignment to s_fss ignored, since the identifier is never used
WARNING:HDLCompiler:1127 - "E:\ohr\cern-fip\trunk\hdl\design\wf_engine_control.vhd" Line 424: Assignment to s_id_dat_ctrl_byte ignored, since the identifier is never used
---> Bugs (which were not reported in Synplify!) corrected!
wf.crc.vhd
c_GENERATOR_POLY_length and c_VERIFICATION_MASK should both come from a generic]
---> I think i wont follow this:-s It would be clear if the: poly_lgth, gener_poly and verif_poly were generics, but this is not possible as gener_poly and verif_poly depend on poly_lgth.
Leaving the 3 signals as constants in the package i think is clearer.
To tom. crc_ok_p is not registered to reduce the number of flip flops, remember this is a rad hard design. It is marcked as p because it is generated using s_crc_bit_ready_p which is already a pulse.
wf_cons_bytes_processor.vhd
line 422. Isn't it possible to check c_CTRL_BYTE_INDEX, c_PDU_BYTE_INDEX upon reception? That would save 16 flip-flops.
---> I think i won't follow that:-s
wf_rx_tx_oscillator.vhd
Interesting note from IEC 61158-2
9.2.6 Preamble
In order to synchronize bit times a preamble shall be transmitted at the beginning of each
PhPDU consisting of the following sequence of bits, shown from left to right in order of
transmission:
1, 0, 1, 0, 1, 0, 1, 0.
(shown as a waveform in Figure 32)
NOTE 1 Received preamble can contain as few as four bits due to loss of one bit through each of four repeaters
(as specified in the MAU Network Configuration Rules).
The period may be extended, but not reduced, by Systems management as given in Table 4.
A preamble extension sequence as listed in Table 4 shall be defined as the following
sequence of bits, shown from left to right in order of transmission:
1, 0, 1, 0, 1, 0, 1, 0.
wf_engine_control.vhd
To Javier. Using std_logic on entity ports is a strong rule in cores. As wf_engine_control.vhd is interfaced with other custom entities this rule should become only a recomendation. Passing var as a custom type gives the possibility to the designer to chose the suitible encoding scheme easily wich is very handy for this critical signal.
To Gonzalo. Receiving to consecutive ID_DAT would be a legal situation? I only see it happening in case an RP_DAT is lost. In that case the watchdog should have reset the control state machine.
Line 775: This process is equivalent to a case statement. The exit is needed to select the case that is driving s_var_id.
WF_status_bytes_gen.vhd
L293.
if (s_var3_rdy_extended = '0' and var3_acc_i = '1') then
-- since the last time the status
s_nFIP_status_byte(c_U_PACER_INDEX) <= '1'; -- byte was delivered,
-- the user logic accessed a prod.
-- var. when it was not ready
end if;
Would it not be easier to use some kind of
---> didnt get that?
wf_rx.vhd
LINE 569: The 16 bit register s_arriving_fes could be removed if the FES arrival is verified bit by bit upon arrival.
---> I think i won't follow that:-s
LINE 663: Is s_CRC_ok_p_buff really needed? I think a flag (or inserting a new state) would be enough.
---> OK! Buffer removed.
NanoFip comments
T. Wlostowski
------------------------
Legend:
B - bug
S - coding style
O - optimization
------------------------
---> I think repository version 125 and not 129 has been used.
General comments
------------------------
- Good work! Very little bugs, most of the comments cover possible optimizations and coding style
- check indentation or pass the code through Emacs ;-)
- avoid excessive empty lines
- use either CR-LF or LF line endings, not both in the same project (or even in the same file),
- remove useless comments, such as "END OF FILE" or a big ascii-art header with name "NanoFIP", "architecture declaration" just above the "architecture" keyword, etc.
- be consequent with prefixing (or not prefixing) signal names (see wf_tx_serializer.vhd:120 for example)
- use identical naming scheme for all generics - somewhere you have "LGTH" in your name, somewhere else - "LENGTH". Prefix generics with "g_".
- avoid commenting obvious stuff (i.e. use std_logic_1164) or duplicating the exact name of the entity/signal/process in its comment.
- use proper architecture names (several architectures are named "rtl", but in fact they containg behavioural code)
- In a big module (such as nanofip top level), grouping all the inputs and then all the outputs altogether doesn't seem for me to be very intuitive. I would recommend grouping I/O ports by interfaces they belong to (and then, inside the interfaces, the inputs and outputs - for example clocks&resets, then Fieldrive I/F, then Wishbone I/F, etc.) and then by the direction (Gonzalo - I'm not against In-Out order).
- Wishbone signals: add wb_ prefix to clearly recognize wb bus among other signals (for example, name "rst_i" says nothing about where the signals belong to)
- Signal declarations: try to group the signals into interfaces connecting individual modules instead of one big and randomly ordered signal declaration. For example:
- keep VHDL file names consistent with entity names (CaSe Is ImPoRtAnT!)
> -- synchronizer <-> rx_tx_osc signals:
> signal s_fd_rxd_edge_p
> signal s_rx_bit_clk_p
> -- engine_control <-> production signals:
> signal s_.....
* Specification:
page 18: Is the WB bus 8-bit or 16-bit? (dat_i/o is 16-bits whereas "data port size" is 8)
---> WISHBONE 8 bits; Stand-alone bus 16 bits.
wf_tx_serializer.vhd
--------------------------
- (S/O) line 305: it's basically a one-hot decoder which is more readable (and takes 5x less space) if written like this:
> s_prepare_to_produce <= '1' when (tx_state = idle) else '0';
> s_sending_FSS <= '1' when (tx_state = send_fss) else '0';
I've noticed you use such ^^^^ syntax in other files.
---> I think i won't change this one:-s I understand that it can be long but i think it is clean and easy to see the value of each signal at each state.
- (S) line 103: tx_clk_p_buff_i is not a clock signal. Remove "clk" from the name, it may be confusing. You're using tx_clk_p_buf_i to arrange serializer operations in time. It would be good for readability of the code to split it into separate signals named according to the phase of serialization they enable or to define appropriate aliases.
---> I think i won't change this one:-s As the unit is written, several different things happen on each pulse so it's even tough to give an appropriate name:-s
- (O) line 236: not really necessary, as the state machine is fully defined.
---> OK! Excessive comment removed!
- (O) line 462: these lines are in fact a part of the state machine (which makes it a Mealy, not Moore-type FSM). Consider moving them to Comb_Output_Signals process.
---> ..hmm..i don't think so:-s All the outputs of the state machine are defined only by the state! Of course then the outputs are used to generate other signals.
- (O) line 501: s_prepare_to_produce, s_sending_FSS actualy represent the TX FSM state in one-hot encoding. There's no need to use if(...) elsif (...) instructions, since they may force the synthesizer to generate a priority encoder which takes more FPGA resources. I would consider using a CASE (tx_state) statement.
---> I think i won't change this one:-s (since i have generated the signals s_prepare_to_produce,s_sending_FSS..etc it would be strange to use the states now; +resources-wise i have margin)
- (O) line 560: s_tx_enable is used only once in the whole entity. Why not drive tx_enable_o directly from bits_to_txd?
---> OK!
wf_bits_to_txd.vhd
--------------------------
- (O) line 141+: sending_xxx signals are mutually exclusive. There's no need for if-elsif constructs.
wf_crc.vhd
--------------------------
- (S) line 98: shouldn't it be crc_ok_o instead of crc_ok_p ?
---> OK! It should actually be crc_ok_p_o!
- (S) line 125: too many generates:
s_q_nx(0) <= data_bit_i xor s_q(s_q'left);
for i in 1 to c_GENERATOR_POLY'left generate s_q_nx(i) <= (....);
---> OK!
- (O) line 182: replace with if(s_q = (not c_VERIFICATION_MASK)), it may save some logic resources (synthesizer will infer a comparator and no XOR gates)
---> OK!
- (O) line 186: avoid driving outputs with comb logic unless it's really justified. Here you can move the CRC comparison to the sequential process above.
---> OK! (despite Pablo's comment regarding saving DFF because of radiation, a 1-uclk delay was essential)
---------------
wf_dualCLKRAM.vhd:
- line 176: check the post-PAR implementation of the voting logic (how it's mapped into LUTs)
----------------------------
wf_manch_encoder.vhd
- (O) lines 107+: the module is quite simple, it implements a simple combinatorial function. It could be implemented as a VHDL function to make the code more compact.
---> OK!
wf_package.vhd
----------------------------
- (S) line 94: do not declare such names (ZERO, ONE) globally or at least prefix them with "c_" to indicate that they are constant.
---> OK!
- (S) line 186: direction of table index - up or down?
---> OK! Corrected.
- (S) line 238: var_whatever - isn't it used in the design to represent an unknow variable? Maybe var_unknown would be a more appropriate name.
---> I think i won't follow this one:-s
- (S) line 998: empty package body
---> OK! function of manch_encoder added.
wf_inputs_synchronizer.vhd
----------------------------
- (O/B) line 104: All WB signals must be synchronous to wb_clk_i, otherwise it will not be compatible with the standard. Don't mark them as asynchronous. I also doubt if the flip-flop chains will do any good here (see Pablo's comment on radiation hardness)
---> OK!
- (S) line 206+, 227+, 263+ - use the same style for implementing sync chains (table or a series of assignments)
---> OK!
- (S) line 238: I understand this line sets the RXD input to 0 when there's no carrier detected to prevent looping back the TX data. It deserves a longer comment. Also, I would consider moving this piece of code to the deserializer. The purpose of wf_inputs_synchronizer should be only the clock domain synchronization, not cleaning TX-RX feedback.
---> OK! FD signals synchronization moved to the WF_FD_receiver unit; Moreover, finally FD_RXCDN is not used in the design in order to make nanoFIP compatible with other tranceivers.
wf_wb_controller.vhd
----------------------------
- (B) line 132: what if wb_adr_id_i[2:1] == 00 and wb_we_i = 1 (the code will recognize this as a read transaction?
---> Bug corrected!
- (B?) line 121/133: reading/writing from an invalid address will hang the bus by not acking the transaction. Is it the expected behaviour?
---> YE$!
wf_reset_unit.vhd
----------------------------
- (S) line 148: confusing signal name. RSTPON_I could mean a REseT on Power ON (active 1), but the comment says it's active low (so shouldn't it be rst_pon_n_i?)
---> It is a signal of nanoFIP's pinout which we would rather not change (it turns out that pinout signals do not follow strictly the guidelines:-s)
JFTR the most appropriate name (following the naming of the rest of the pinout signals) would be PORN..which turns out rather inappropriate 8-)
- (S) line 152: avoid using complex data types in entity ports. Maybe replace with port var_is_rst_i = (var_i == var_rst)?
---> Pablo..
- (O) line 207: why not use rstpon_i directly in the code, without inverting it?
---> OK!
- (O) line 209: the only purpose of s_transm_period is to be multiplied by 2 in the next line. Consider removing this signal.
- (S) line 216: "s_c" says nothing about the purpose of the signal.
---> OK! (..but it actually meant signal_counter which is all it does:-p)
- (O) line 216: singal s_counter_full is assigned only to s_counter_is_full which drives only one load ("if" in line 295). The counter could be compared directly in the FSM process.
---> OK!
- (S/O) lines 274, 285: the same applies to s_counter_is_ten, s_counter_is_four. Reduce the number of signals, they are really messing up the code!
---> OK!
- (S) line 455 (and other case entries): use a bit shorter names for the FSM states. Add comments explaining their purposes.
---> OK!
- (O) line 616: mark rston_o (or s_rston) as an active-high (low) signal or get rid of the inversion by driving s_rst with inverted values in process Resets_after_a_var_rst_Comb_State_Transitions.
---> OK!
wf_rx_tx_osc.vhd
----------------------------
- (S) line 108/116: LGTH or LENGTH?
---> OK! Only LGTH kept in all the design.
- (S) line 212/261: here you have processes with rx/tx counters, but in other files you instantiate an up/down counter block. Be consistent :)
---> OK! wf_incr_counters used!
- (B) line 229: what if the device hasn't received yet any frames and there is a glitch on the FIP bus (so s_rx_counter gets reset at a wrong moment, desynchronizing the rest)?
---> ..I think that wouldn't be a problem as the deserializer would see that it was a glitch (since following expected edges will not appear) and would reset the oscillator; glitches within the preamble could be a problem though+that is why the deglitcher unit has changed!
- (O) line 234: merge this condition into if in line 229.
---> OK!
- (O) lines 302,310,etc: why generate a clock if you can generate output pulses directly here?
- (O) lines 254/258: since half_period = period >> 1, one_forth_period = period >> 2 and jitter = period >> 3 and counter is counting from 0 to period, we could optimize this a bit:
> rxd_signif_edge_window signal:
>
> value of s_rx_counter: expanded value: results of comparisons:
> 0 0 rxd_signif_edge_window <= 1
> jitter period/8 rxd_signif_edge_window <= 0
> s_counter_full-jitter-1 pediod*7/8 rxd_signif_edge_window <= 1
>
> rx_adjac_bits_window:
> 0 0 rx_adjac_bits_window <= 1
> s_half_period-s_jitter-1 period*3/4 rx_adjac_bits_window <= 0
> (...) and so on and so forth
All expanded values are multipies of (s_period/8), so you could use a counter counting up to (s_period/8) and a state machine changing the signals above every time it reaches its maximum value. This optimization requires period to be a multiple of 8 (which is true for all bus speeds and 40 MHz uclk).
lines 361+: the whole process and comb logic around can be turned into a simple counter counting up to period/4 and generating a pulse on tx_clk_p_o everytime the counter overflows.
---> ..I think i won't follow this one:-s
- POSSIBLE SERIOUS BUG: The bit-window locking seems to be using the first transition in the RXD signal to synchronize the counter in rx_tx_osc. A small glitch in the signal just before the preamble could cause a valid frame to be dropped because of an invalid data window. RX clock should be locked *after* receiving the preamble, not before - this is the purpose of preambles in all data links.
---> Hmm..glitches just before the preamble wouldn't be a problem..the FSM of the deserializer would not find the next edge where expected and the whole procedure would start all over again. The problem would be glitches inside the preamble+that is why the deglitcher unit has been changed!
wf_rx_deserializer.vhd:
-------------------------
- (O) line 635+ (entire process): 15 bit-long delay can be shortened to 1 bit-long delay by storing the result of CRC check upon reception of every byte instead of every bit. Then, if an FES is received it's enough to check. This way we could save some flip-flops (and possibly improve the robustness in radiation environment).
---> OK!
- (O) line 424: this case is never reached
---> Not sure..u mean the "when others"? That is essential for recovery from SEU
wf_cons_bytes_to_dato.vhd
--------------------------
- (O) whole files: Is it really necessary to implement such simple jobs in separate entities instantiated in a single place in the whole design?
---> OK!
wf_cons_frame_validator.vhd
--------------------------
- (O) line 206: it in fact does this:
> var_type_match <= '1' when (var_i = var_1 or var_i = var_2 or var_i=var_rst) else '0'; --helper code
>
> cons_frame_ok_p_o <= '1' when
> var_type_match = '1'
> and cons_ctrl_byte_i = c_RP_DAT_CTRL_BYTE
> and cons_pdu_byte_i = c_PROD_CONS_PDU_TYPE_BYTE
> and unsigned(rx_byte_index_i) = unsigned(cons_lgth_byte_i) + 5
> else '0';
- line 211: value of nfip_status_r_tler_o is equal to cons_frame_ok_p_o (because s_cons_lgth_bytes_ok depends on rx_fss_crc_fes_manch_ok_p_i already)
This can be simply integrated into WF_consumption.vhd, it would take less than the instantiation of the validator entity.
---> OK! Process shrunk+incorporated inside the WF_cons_outcome unit! Also bug corrected regarding the length byte which makes nfip_status_r_tler_o different to cons_frame_ok_p_o(comments to gonzalo)
wf_cons_outcome.vhd
-------------------------
- (S/O) line 239+: the delay could be done in the module which drives var_i and cons_frame_ok_p_i to avoid weird timing relations on interfaces connecting the modules. That would greatly help with analysis of simulation waveforms.
---> OK!
wf_engine_control.vhd
---------------------------
- (S) line 118: unused generic.
---> OK! Removed.
- (B) line 303: what if the frame gets terminated when the FSM is in id_dat_control_byte or id_dat_var_byte? Could possibly cause losing the next frame. The FSM should always return to IDLE state from every other state in case of a failure in data reception (and possibly a timeout).
---> No problem if the frame gets terminated when the FSM is in id_dat_control_byte or id_dat_var_byte! If the control or the var bytes are not as expected the FSM goes anyway to idle (neither the var nor the control bytes match the FES).
---> OK! Timeout added!
- (O) line 424: the whole process could be shrunk into 8 lines.
---> I think i won't follow this one:-s
- (S) lines 661,671: if you used only SL/SLV in module ports, you wouldn't have to apply any conversions here.
---> ..but i would have to apply them to many other units:-s
wf_prod_bytes_to_dati.vhd
---------------------------
- (S) line 134: again - assure proper timing in the driver.
---> OK!
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment