KONRAD Frederic

send an IRQ transaction on level edge only.

This removes a bug where the IRQ is sent more than one time when it shouldn't.
The current irq level is a gs_param so it can be analyzed with GreenAV later.

Signed-off-by: KONRAD Frederic <fred.konrad@greensocs.com>
... ... @@ -75,6 +75,7 @@ class APB_UART:
gs::gs_param<unsigned int> irqNumber; /*<! IRQ line number. */
gs::gs_param<uint8_t> input_buffer; /*<! Place where RX data is written. */
uint32_t internal_int; /*<! Internal interrupt status. */
gs::gs_param<bool> irq_level; /*<! Current irq_level. */
void end_of_elaboration();
void ClearIRQ(gs::reg::transaction_type *&tr, const sc_core::sc_time &delay);
... ...
... ... @@ -64,7 +64,8 @@ APB_UART::APB_UART(sc_module_name nm):
irq_socket("irq_socket"),
serial_sock("serial_socket"),
irqNumber("irq_number", "0"),
input_buffer("input_buffer", "0")
input_buffer("input_buffer", "0"),
irq_level("irq_level", "0")
{
serial_sock.register_b_transport(this, &APB_UART::serial_b_transport);
gs::socket::config<gs_generic_signal::gs_generic_signal_protocol_types> cnf;
... ... @@ -163,10 +164,14 @@ void APB_UART::UpdateIRQ(void)
/* Update the IRQ line. */
data.value = ((r[INTSTATUS] & ((r[CTRL] >> 2) & 0x0F)) != 0);
data.irq_line = irqNumber;
payload.set_data_ptr((unsigned char *) &data);
payload.set_ack_requirement(ack_requirement);
irq_socket.validate_extension<IRQ_LINE_EXTENSION>(payload);
irq_socket->b_transport(payload, time);
if ((data.value != 0) ^ (this->irq_level))
{
this->irq_level = (data.value != 0);
payload.set_data_ptr((unsigned char *) &data);
payload.set_ack_requirement(ack_requirement);
irq_socket.validate_extension<IRQ_LINE_EXTENSION>(payload);
irq_socket->b_transport(payload, time);
}
}
void APB_UART::WriteData(gs::reg::transaction_type *&tr,
... ...