596 lines
19 KiB
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} += {path}_incr_val{genvars};
|
|
{path}_next{genvars} -= {path}_decr_val{genvars};
|
|
end
|
|
end
|
|
else if ({path}_incr{genvars})
|
|
begin
|
|
if (!{path}_incr_sat{genvars})
|
|
<<INDENT>>
|
|
{path}_next{genvars} += {path}_incr_val{genvars};
|
|
<<UNINDENT>>
|
|
end
|
|
else if ({path}_decr{genvars})
|
|
begin
|
|
if (!{path}_decr_sat{genvars})
|
|
<<INDENT>>
|
|
{path}_next{genvars} += {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} = {path}_q{genvars} + ({{{incr_width}{{{path}_incr}}}} & {path}_incr_val) - ({{{decr_width}{{{path}_decr}}}} & {path}_decr_val) > {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} = {path}_q{genvars} + ({{{incr_width}{{{path}_incr}}}} & {path}_incr_val) - ({{{decr_width}{{{path}_decr}}}} & {path}_decr_val) > {sat_value};
|
|
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} = {path}_q{genvars} + ({{{incr_width}{{{path}_incr}}}} & {path}_incr_val) - ({{{decr_width}{{{path}_decr}}}} & {path}_decr_val) > {thr_value};
|
|
output_ports:
|
|
- name: '{path}_incr_thr'
|
|
signal_type: 'logic'
|
|
counter_decr_thr:
|
|
rtl: |-
|
|
assign {path}_decr_thr{genvars} = {path}_q{genvars} + ({{{incr_width}{{{path}_incr}}}} & {path}_incr_val) - ({{{decr_width}{{{path}_decr}}}} & {path}_decr_val) > {thr_value};
|
|
output_ports:
|
|
- name: '{path}_decr_thr'
|
|
signal_type: 'logic'
|
|
counter_overflow:
|
|
rtl: |-
|
|
|
|
// Logic to determine occurance of an overflow
|
|
assign {path}_overflow_int{genvars} = {path}_q{genvars} + ({{{incr_width}{{{path}_incr}}}} & {path}_incr_val) - ({{{decr_width}{{{path}_decr}}}} & {path}_decr_val) > {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) - ({{{decr_width}{{{path}_decr}}}} & {path}_decr_val) > {underflow_value};
|
|
assign {path}_underflow{genvars} = {path}_incr{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
|