srdl2sv/srdl2sv/components/templates/fields.yaml

596 lines
19 KiB
YAML

---
sense_list_rst:
rtl: |-
always_ff @(posedge clk or {rst_edge} {rst_name})
sense_list_no_rst:
rtl: |-
always_ff @(posedge clk)
rst_field_assign:
rtl: |-
if ({rst_negl}{rst_name})
begin
{path}_q{genvars} <= {width}'d{rst_value};
end
else
signals:
- name: '{path}_q'
signal_type: '{field_type}'
sw_access_field:
rtl: |-
if ({path_wo_field}_sw_wr{genvars})
begin
sw_access_field_swwe:
rtl: |-
if ({path_wo_field}_sw_wr{genvars} && {swwe}) // swwe property
begin
sw_access_field_swwel:
rtl: |-
if ({path_wo_field}_sw_wr{genvars} && !{swwel}) // swwel property
begin
sw_access_byte:
rtl: |-
if (widget_if.byte_en[{i}])
<<INDENT>>
{path}_q{genvars}[{msb_field}:{lsb_field}] <= widget_if.w_data[{msb_bus}:{lsb_bus}];
<<UNINDENT>>
signals:
- name: '{path}_q'
signal_type: '{field_type}'
hw_enable_mask_start:
rtl: |-
for (int idx = 0; idx < {width}; idx++)
begin
if ({negl}{signal}[idx])
<<INDENT>>
hw_enable_mask_end:
rtl: |-
<<UNINDENT>>
end // for (int idx = 0; idx < {width}; idx++)
hw_access_we_wel:
rtl: |-
if ({negl}{path}_hw_wr{genvars})
input_ports:
- name: '{path}_hw_wr'
signal_type: 'logic'
hw_access_no_we_wel:
rtl: |-
<<INDENT>>
// we or wel property not set
<<UNINDENT>>
hw_access_hwset:
rtl: |-
if ({path}_hwset{genvars})
<<INDENT>>
{enable_mask_start}
{path}_q{genvars}{idx} <= {constant};
{enable_mask_end}
<<UNINDENT>>
input_ports:
- name: '{path}_hwset'
signal_type: 'logic'
hw_access_hwclr:
rtl: |-
if ({path}_hwclr{genvars})
<<INDENT>>
{enable_mask_start}
{path}_q{genvars}{idx} <= {constant};
{enable_mask_end}
<<UNINDENT>>
input_ports:
- name: '{path}_hwclr'
signal_type: 'logic'
hw_access_field:
rtl: |-
<<INDENT>>
{enable_mask_start}
{path}_q{genvars}{idx} <= {assignment};
{enable_mask_end}
<<UNINDENT>>
signals:
- name: '{path}_q'
signal_type: '{field_type}'
hw_access_field__assignment__input:
rtl: |-
{path}_in{genvars}{idx}
input_ports:
- name: '{path}_in'
signal_type: '{field_type}'
hw_access_counter:
rtl: |-
if ({path}_incr{genvars} || {path}_decr{genvars})
<<INDENT>>
{enable_mask_start}
{path}_q{genvars}{idx} <= {path}_next{genvars}{idx};
{enable_mask_end}
<<UNINDENT>>
signals:
- name: '{path}_update_cnt'
signal_type: 'logic'
- name: '{path}_next'
signal_type: '{field_type}'
hw_const:
rtl: |-
// Field is defined as a constant.
assign {path}_q{genvars} = {width}'d{const};
signals:
- name: '{path}_q'
signal_type: '{field_type}'
hw_wire:
rtl: |-
// Field is a simple wire.
// To generate a flop either add the we/wel property, add
// a reset, or change the sw/hw access properties
assign {path}_q{genvars} = {path}_in{genvars};
signals:
- name: '{path}_q'
signal_type: '{field_type}'
input_ports:
- name: '{path}_in'
signal_type: '{field_type}'
end_field_ff:
rtl: |-
end // of {path}'s always_ff
OnWriteType.woset:
rtl: |-
if (widget_if.byte_en[{i}]) // woset property
<<INDENT>>
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {path}_q{genvars}[{msb_field}:{lsb_field}] | widget_if.w_data[{msb_bus}:{lsb_bus}];
<<UNINDENT>>
OnWriteType.woclr:
rtl: |-
if (widget_if.byte_en[{i}]) // woclr property
<<INDENT>>
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {path}_q{genvars}[{msb_field}:{lsb_field}] & ~widget_if.w_data[{msb_bus}:{lsb_bus}];
<<UNINDENT>>
OnWriteType.wot:
rtl: |-
if (widget_if.byte_en[{i}]) // wot property
<<INDENT>>
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {path}_q{genvars}[{msb_field}:{lsb_field}] ^ widget_if.w_data[{msb_bus}:{lsb_bus}];
<<UNINDENT>>
OnWriteType.wzs:
rtl: |-
if (widget_if.byte_en[{i}]) // wzs property
<<INDENT>>
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {path}_q{genvars}[{msb_field}:{lsb_field}] & widget_if.w_data[{msb_bus}:{lsb_bus}];
<<UNINDENT>>
OnWriteType.wzt:
rtl: |-
if (widget_if.byte_en[{i}]) // wzt property
<<INDENT>>
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {path}_q{genvars}[{msb_field}:{lsb_field}] ~^ widget_if.w_data[{msb_bus}:{lsb_bus}];
<<UNINDENT>>
OnWriteType.wclr:
rtl: |-
if (widget_if.byte_en[{i}]) // wclr property
<<INDENT>>
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {width}'b0;
<<UNINDENT>>
OnWriteType.wset:
rtl: |-
if (widget_if.byte_en[{i}]) // wclr property
<<INDENT>>
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {{{width}{{1'b1}}}};
<<UNINDENT>>
sw_read_access_field:
rtl: |-
if ({path_wo_field}_sw_rd{genvars})
begin
OnReadType.rclr:
rtl: |-
if (widget_if.byte_en[{i}]) // rclr property
<<INDENT>>
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {width}'b0;
<<UNINDENT>>
OnReadType.rset:
rtl: |-
if (widget_if.byte_en[{i}]) // rset property
<<INDENT>>
{path}_q{genvars}[{msb_field}:{lsb_field}] <= {{{width}{{1'b1}}}};
<<UNINDENT>>
field_comment:
rtl: |-
//-----------------FIELD SUMMARY-----------------
// name : {name} ({path_wo_field}[{msb}:{lsb}])
// access : hw = {hw_access} {hw_precedence}
// sw = {sw_access} {sw_precedence}
// reset : {rst_active} / {rst_type}
// flags : {misc_flags}
// external : {external}
// storage type : {storage_type}
//-----------------------------------------------
description:
rtl: |-
/********************DESCRIPTION*****************
{desc}
/************************************************/
combo_operation_comment:
rtl: |-
// Combinational logic for {path}
assign_anded_operation:
rtl: |-
assign {path}_anded{genvars} = {op_verilog}{path}_q{genvars};
output_ports:
- name: '{path}_anded'
signal_type: 'logic'
assign_ored_operation:
rtl: |-
assign {path}_ored{genvars} = {op_verilog}{path}_q{genvars};
output_ports:
- name: '{path}_ored'
signal_type: 'logic'
assign_xored_operation:
rtl: |-
assign {path}_xored{genvars} = {op_verilog}{path}_q{genvars};
output_ports:
- name: '{path}_xored'
signal_type: 'logic'
singlepulse:
rtl: |-
begin
{path}{genvars}_q <= 0;
end
out_port_assign:
rtl: |-
// Connect register to hardware output port
assign {path}_r{genvars} = {path}_q{genvars};
output_ports:
- name: '{path}_r'
signal_type: '{field_type}'
swacc_assign:
rtl: |-
// Combinational block to generate swacc-output signals
assign {path}_swacc{genvars} = ({path_wo_field}__any_alias_sw_wr{genvars} || {path_wo_field}__any_alias_sw_rd{genvars}) && |widget_if.byte_en[{msbyte}:{lsbyte}];
output_ports:
- name: '{path}_swacc'
signal_type: 'logic'
swmod_always_comb:
rtl: |-
// Combinational block to generate swmod-output signals
always_comb
begin
{path}_swmod{genvars} = 0;
{swmod_assigns}
end
output_ports:
- name: '{path}_swmod'
signal_type: 'logic'
swmod_assign:
rtl: |-
{path}_swmod{genvars} |= {path_wo_field}__any_alias_sw_{rd_wr}{genvars} && |widget_if.byte_en[{msbyte}:{lsbyte}];
output_ports:
- name: '{path}_swmod'
signal_type: 'logic'
counter_comment:
rtl: |-
/***********************
* Counter Combo Logic *
***********************/
counter:
rtl: |-
// Combinational logic that implements counter
// Note that the three branches for all three possibilities
// are implemented but that either the _incr or the _decr value
// might be tied to 0.
always_comb
begin
{path}_next{genvars} = {path}_q{genvars};
if ({path}_incr{genvars} && {path}_decr{genvars})
begin
if (!{path}_incr_sat{genvars} && !{path}_decr_sat{genvars})
begin
{path}_next{genvars} += {{{incr_zero_pad}{path}_incr_val{genvars}}};
{path}_next{genvars} -= {{{decr_zero_pad}{path}_decr_val{genvars}}};
end
end
else if ({path}_incr{genvars})
begin
if (!{path}_incr_sat{genvars})
<<INDENT>>
{path}_next{genvars} += {{{incr_zero_pad}{path}_incr_val{genvars}}};
<<UNINDENT>>
end
else if ({path}_decr{genvars})
begin
if (!{path}_decr_sat{genvars})
<<INDENT>>
{path}_next{genvars} -= {{{decr_zero_pad}{path}_decr_val{genvars}}};
<<UNINDENT>>
end
end
signals:
- name: '{path}_next'
signal_type: '{field_type}'
counter_internal_incr_val_signal:
rtl: |-
assign {path}_incr_val{genvars} = {incr_value};
signals:
- name: '{path}_incr_val'
signal_type: 'logic [{incr_width}:0]'
counter_internal_decr_val_signal:
rtl: |-
assign {path}_decr_val{genvars} = {decr_value};
signals:
- name: '{path}_decr_val'
signal_type: 'logic [{decr_width}:0]'
counter_incr_val_input:
rtl: ''
input_ports:
- name: '{path}_incr_val'
signal_type: 'logic [{incr_width}:0]'
counter_decr_val_input:
rtl: ''
input_ports:
- name: '{path}_decr_val'
signal_type: 'logic [{decr_width}:0]'
counter_internal_incr_signal:
rtl: |-
assign {path}_incr{genvars} = {incr};
signals:
- name: '{path}_incr'
signal_type: 'logic'
counter_internal_decr_signal:
rtl: |-
assign {path}_decr{genvars} = {decr};
signals:
- name: '{path}_decr'
signal_type: 'logic'
counter_incr_input:
rtl: ''
input_ports:
- name: '{path}_incr'
signal_type: ''
counter_decr_input:
rtl: ''
input_ports:
- name: '{path}_decr'
signal_type: ''
counter_incr_sat:
rtl: |-
// Determine whether the counter is saturated
// The signal is tied if the counter is not saturating
// in the respective direction
assign {path}_incr_sat{genvars} = {{1'b0, {path}_q{genvars}}} + ({{{width_plus_1}{{{path}_incr}}}} & {{{incr_sat_zero_pad}{path}_incr_val}}) - ({{{width_plus_1}{{{path}_decr}}}} & {{{decr_sat_zero_pad}{path}_decr_val}}) > {{1'b0, {sat_value}}};
signals:
- name: '{path}_incr_sat'
signal_type: 'logic'
counter_incr_sat_tied:
rtl: |-
// Determine whether the counter is saturated
// The signal is tied if the counter is not saturating
// in the respective direction
assign {path}_incr_sat{genvars} = 1'b0;
signals:
- name: '{path}_incr_sat'
signal_type: 'logic'
counter_decr_sat:
rtl: |-
assign {path}_decr_sat{genvars} = {{1'b0, {path}_q{genvars}}} + ({{{width_plus_1}{{{path}_incr}}}} & {{{incr_sat_zero_pad}{path}_incr_val}}) < {{1'b0, {sat_value}}} + ({{{width_plus_1}{{{path}_decr}}}} & {{{decr_sat_zero_pad}{path}_decr_val}});
signals:
- name: '{path}_decr_sat'
signal_type: 'logic'
counter_decr_sat_tied:
rtl: |-
assign {path}_decr_sat{genvars} = 1'b0;
signals:
- name: '{path}_decr_sat'
signal_type: 'logic'
counter_thr_comment:
rtl: |-
// Define threshold signals (similar to overflow, but for a user specified value)
counter_incr_thr:
rtl: |-
assign {path}_incr_thr{genvars} = {{1'b0, {path}_q{genvars}}} + ({{{width_plus_1}{{{path}_incr}}}} & {{{incr_sat_zero_pad}{path}_incr_val}}) - ({{{width_plus_1}{{{path}_decr}}}} & {{{decr_sat_zero_pad}{path}_decr_val}}) >= {{1'b0, {thr_value}}};
output_ports:
- name: '{path}_incr_thr'
signal_type: 'logic'
counter_decr_thr:
rtl: |-
assign {path}_decr_thr{genvars} = {{1'b0, {path}_q{genvars}}} + ({{{width_plus_1}{{{path}_incr}}}} & {{{incr_sat_zero_pad}{path}_incr_val}}) <= {{1'b0, {thr_value}}} + ({{{width_plus_1}{{{path}_decr}}}} & {{{decr_sat_zero_pad}{path}_decr_val}}) ;
output_ports:
- name: '{path}_decr_thr'
signal_type: 'logic'
counter_overflow:
rtl: |-
// Logic to determine occurance of an overflow
assign {path}_overflow_int{genvars} = {{1'b0, {path}_q{genvars}}} + ({{{width_plus_1}{{{path}_incr}}}} & {{{incr_sat_zero_pad}{path}_incr_val}}) - ({{{width_plus_1}{{{path}_decr}}}} & {{{decr_sat_zero_pad}{path}_decr_val}}) > {{1'b0, {overflow_value}}};
assign {path}_overflow{genvars} = {path}_incr{genvars} && {path}_overflow_int{genvars};
signals:
- name: '{path}_overflow_int'
signal_type: 'logic'
output_ports:
- name: '{path}_overflow'
signal_type: 'logic'
counter_underflow:
rtl: |-
// Logic to determine occurance of an underflow
assign {path}_underflow_int{genvars} = {path}_q{genvars} + ({{{incr_width}{{{path}_incr}}}} & {path}_incr_val) > {underflow_value} + ({{{decr_width}{{{path}_decr}}}} & {path}_decr_val) ;
assign {path}_underflow{genvars} = {path}_decr{genvars} && {path}_underflow_int{genvars};
signals:
- name: '{path}_underflow_int'
signal_type: 'logic'
output_ports:
- name: '{path}_underflow'
signal_type: 'logic'
external_rd_assignments:
rtl: |-
/**********************************
* Handle external read interface *
**********************************
* The '{path}_ext_r_req' output will be asserted once a read
* is requested by the bus and will stay high until '{path}_ext_r_ack'
* gets set. During a read, byte-enables will be ignored.
*
* '{path}_ext_r_ack' shall be held 1'b1 until all fields in the register
* acknowledged the read. In practice, this means until '{path}_ext_r_req'
* goes back to 1'b0.
*
* If '{path}_ext_r_err' gets set, it must also be held during the
* complete time '{path}_ext_r_ack' is high.
*/
// Actual data
assign {path}_ext_r_req{genvars} = {path_wo_field}_sw_rd{genvars};
// Assign return from outside hardware
assign {path}_q{genvars} = {path}_ext_r_data;
signals:
- name: '{path}_q'
signal_type: '{field_type}'
input_ports:
- name: '{path}_ext_r_data'
signal_type: '{field_type}'
- name: '{path}_ext_r_ack'
signal_type: ''
- name: '{path}_ext_r_err'
signal_type: ''
output_ports:
- name: '{path}_ext_r_req'
signal_type: 'logic'
external_wr_assignments:
rtl: |-
/***********************************
* Handle external write interface *
***********************************
* The '{path}_ext_w_req' output will be asserted once a write
* is requested by the bus and will stay high until '{path}_ext_w_ack'
* gets set. During a write, hardware shall not touch any bits that
* are not defined in '{path}_ext_w_mask'.
*
* '{path}_ext_w_ack' shall be held 1'b1 until all fields in the register
* acknowledged the read. In practice, this means until '{path}_ext_w_req'
* goes back to 1'b0.
*
* If '{path}_ext_w_err' gets set, it must also be held during the
* complete time '{path}_ext_w_ack' is high.
*/
// Write request
assign {path}_ext_w_req{genvars} = {path_wo_field}_sw_wr{genvars};
// Assign value from bus to output
assign {path}_ext_w_data{genvars} = widget_if.w_data[{msb_bus}:{lsb_bus}];
// Provide bit-wise mask. Only bits set to 1'b1 shall be written
assign {path}_ext_w_mask{genvars} = {{{mask}}};
output_ports:
- name: '{path}_ext_w_req'
signal_type: 'logic'
- name: '{path}_ext_w_data'
signal_type: '{field_type}'
- name: '{path}_ext_w_mask'
signal_type: 'logic [{width}:0]'
input_ports:
- name: '{path}_ext_w_ack'
signal_type: ''
- name: '{path}_ext_w_err'
signal_type: ''
external_wr_mask_segment:
rtl: |-
{{{width}{{widget_if.byte_en[{idx}]}}}}
trigger_input:
rtl: |-
{path}_in
input_ports:
- name: '{path}_in'
signal_type: '{field_type}'
rst_intr_header:
rtl: |-
if ({rst_negl}{rst_name})
<<INDENT>>
{trigger_signal}_q{genvars} <= 1'b0;
<<UNINDENT>>
else
signals:
- name: '{trigger_signal}_q'
signal_type: '{field_type}'
always_ff_block_intr:
rtl: |-
// Flops to generate appropriate interrupt signal
{always_ff_header}
{reset_intr_header}
<<INDENT>>
{trigger_signal}_q{genvars} <= {trigger_signal}{genvars};
<<UNINDENT>>
signals:
- name: '{trigger_signal}_q'
signal_type: '{field_type}'
InterruptType.posedge:
rtl: |-
// Define signal that causes the interrupt to be set (posedge-type interrupt)
assign {path}_sticky_latch{genvars} = !{trigger_signal}_q{genvars} & {trigger_signal}{genvars};
signals:
- name: '{path}_sticky_latch'
signal_type: '{field_type}'
InterruptType.negedge:
rtl: |-
// Define signal that causes the interrupt to be set (negedge-type interrupt)
assign {path}_sticky_latch{genvars} = {trigger_signal}_q{genvars} & !{trigger_signal}{genvars};
signals:
- name: '{path}_sticky_latch'
signal_type: '{field_type}'
InterruptType.bothedge:
rtl: |-
// Define signal that causes the interrupt to be set (bothedge-type interrupt)
assign {path}_sticky_latch{genvars} = ({trigger_signal}_q{genvars} & !{trigger_signal}{genvars}) | (!{trigger_signal}_q{genvars} & {trigger_signal}{genvars});
signals:
- name: '{path}_sticky_latch'
signal_type: '{field_type}'
InterruptType.level:
rtl: |-
// Define signal that causes the interrupt to be set (level-type interrupt)
assign {path}_sticky_latch{genvars} = {trigger_signal}{genvars};
signals:
- name: '{path}_sticky_latch'
signal_type: '{field_type}'
sticky:
rtl: |-
if (|{path}_sticky_latch{genvars} && !(|{path}_q{genvars}))
begin
// Sticky. Keep value until software clears it
{path}_q{genvars} <= {trigger_signal};
end
signals:
- name: '{path}_sticky_latch'
signal_type: '{field_type}'
stickybit:
rtl: |-
begin
for (int i = 0; i < {width}; i++)
begin
if ({path}_sticky_latch{genvars}[i])
begin
// Stickybit. Keep value until software clears it
{path}_q{genvars}[i] <= 1'b1;
end
end
end
signals:
- name: '{path}_sticky_latch'
signal_type: '{field_type}'
nonsticky_intr:
rtl: |-
begin
// Non-sticky interrupt. Only keep value high if source keeps up
{path}_q{genvars} <= {assignment};
end