Skip to content

Commit

Permalink
Edge sensitive sysctl irqs
Browse files Browse the repository at this point in the history
  • Loading branch information
lekernel committed Nov 13, 2009
1 parent f061a30 commit f02c2a7
Show file tree
Hide file tree
Showing 12 changed files with 69 additions and 57 deletions.
17 changes: 8 additions & 9 deletions boards/avnet-sp3aevl/rtl/system.v
Expand Up @@ -334,7 +334,6 @@ csrbrg csrbrg(
)
);


//---------------------------------------------------------------------------
// Interrupts
//---------------------------------------------------------------------------
Expand All @@ -344,13 +343,13 @@ wire timer1_irq;
wire uartrx_irq;
wire uarttx_irq;

wire [31:0] cpu_interrupt_n;
assign cpu_interrupt_n = {{27{1'b1}},
~uarttx_irq,
~uartrx_irq,
~timer1_irq,
~timer0_irq,
~gpio_irq
wire [31:0] cpu_interrupt;
assign cpu_interrupt = {27'd0,
uarttx_irq,
uartrx_irq,
timer1_irq,
timer0_irq,
gpio_irq
};

//---------------------------------------------------------------------------
Expand All @@ -359,7 +358,7 @@ assign cpu_interrupt_n = {{27{1'b1}},
lm32_top cpu(
.clk_i(sys_clk),
.rst_i(sys_rst),
.interrupt_n(cpu_interrupt_n),
.interrupt(cpu_interrupt),

.I_ADR_O(cpuibus_adr),
.I_DAT_I(cpuibus_dat_r),
Expand Down
28 changes: 14 additions & 14 deletions boards/milkymist-one/rtl/system.v
Expand Up @@ -580,19 +580,19 @@ wire ac97dmaw_irq;
wire pfpu_irq;
wire tmu_irq;

wire [31:0] cpu_interrupt_n;
assign cpu_interrupt_n = {{21{1'b1}},
~tmu_irq,
~pfpu_irq,
~ac97dmaw_irq,
~ac97dmar_irq,
~ac97crreply_irq,
~ac97crrequest_irq,
~uarttx_irq,
~uartrx_irq,
~timer1_irq,
~timer0_irq,
~gpio_irq
wire [31:0] cpu_interrupt;
assign cpu_interrupt = {21'd0,
tmu_irq,
pfpu_irq,
ac97dmaw_irq,
ac97dmar_irq,
ac97crreply_irq,
ac97crrequest_irq,
uarttx_irq,
uartrx_irq,
timer1_irq,
timer0_irq,
gpio_irq
};

//---------------------------------------------------------------------------
Expand All @@ -601,7 +601,7 @@ assign cpu_interrupt_n = {{21{1'b1}},
lm32_top cpu(
.clk_i(sys_clk),
.rst_i(sys_rst),
.interrupt_n(cpu_interrupt_n),
.interrupt(cpu_interrupt),

.I_ADR_O(cpuibus_adr),
.I_DAT_I(cpuibus_dat_r),
Expand Down
3 changes: 2 additions & 1 deletion boards/xilinx-ml401/synthesis/common.ucf
Expand Up @@ -338,6 +338,7 @@ NET "ac97_sync" LOC = D9 | IOSTANDARD = LVCMOS25;
NET "ac97_clk" TNM_NET = "clkac97";
TIMESPEC "TSclkac97" = PERIOD "clkac97" 80 HIGH 50%;

# PS2 signals
# ==== PS/2 ====
# "keyboard" connector
NET "ps2_clk1" LOC = D2 | IOSTANDARD = LVCMOS25;
NET "ps2_data1" LOC = G9 | IOSTANDARD = LVCMOS25;
47 changes: 27 additions & 20 deletions cores/sysctl/rtl/sysctl.v
Expand Up @@ -25,10 +25,10 @@ module sysctl #(
input sys_rst,

/* Interrupts */
output gpio_irq,
output timer0_irq,
output timer1_irq,
output reg gpio_irq,
output reg timer0_irq,
output reg timer1_irq,

/* CSR bus interface */
input [13:0] csr_a,
input csr_we,
Expand All @@ -55,13 +55,14 @@ end
/* Detect level changes and generate IRQs */
reg [ninputs-1:0] gpio_inbefore;
always @(posedge sys_clk) gpio_inbefore <= gpio_in;

reg [ninputs-1:0] gpio_irqact;
reg [ninputs-1:0] gpio_irqen;

wire [ninputs-1:0] gpio_diff = gpio_inbefore ^ gpio_in;

assign gpio_irq = |(gpio_irqact & gpio_irqen);
reg [ninputs-1:0] gpio_irqen;
always @(posedge sys_clk) begin
if(sys_rst)
gpio_irq <= 1'b0;
else
gpio_irq <= |(gpio_diff & gpio_irqen);
end

/*
* Dual timer
Expand All @@ -88,9 +89,11 @@ wire csr_selected = csr_a[13:10] == csr_addr;
always @(posedge sys_clk) begin
if(sys_rst) begin
csr_do <= 32'd0;

timer0_irq <= 1'b0;
timer1_irq <= 1'b0;

gpio_outputs <= {noutputs{1'b0}};
gpio_irqact <= {ninputs{1'b0}};
gpio_irqen <= {ninputs{1'b0}};

en0 <= 1'b0;
Expand All @@ -104,18 +107,24 @@ always @(posedge sys_clk) begin
compare0 <= 32'hFFFFFFFF;
compare1 <= 32'hFFFFFFFF;
end else begin
/* Handle GPIO */
gpio_irqact <= gpio_irqact|gpio_diff;
timer0_irq <= 1'b0;
timer1_irq <= 1'b0;

/* Handle timer 0 */
if( en0 & ~match0) counter0 <= counter0 + 32'd1;
if( en0 & match0) trig0 <= 1'b1;
if( en0 & match0) begin
trig0 <= 1'b1;
timer0_irq <= 1'b1;
end
if( ar0 & match0) counter0 <= 32'd1;
if(~ar0 & match0) en0 <= 1'b0;

/* Handle timer 1 */
if( en1 & ~match1) counter1 <= counter1 + 32'd1;
if( en1 & match1) trig1 <= 1'b1;
if( en1 & match1) begin
trig1 <= 1'b1;
timer1_irq <= 1'b1;
end
if( ar1 & match1) counter1 <= 32'd1;
if(~ar1 & match1) en1 <= 1'b0;

Expand All @@ -127,8 +136,7 @@ always @(posedge sys_clk) begin
/* GPIO registers */
// 0000 is GPIO IN and is read-only
4'b0001: gpio_outputs <= csr_di[noutputs-1:0];
4'b0010: gpio_irqact <= (gpio_irqact|gpio_diff) & ~csr_di[ninputs-1:0];
4'b0011: gpio_irqen <= csr_di[ninputs-1:0];
4'b0010: gpio_irqen <= csr_di[ninputs-1:0];

/* Timer 0 registers */
4'b0100: begin
Expand All @@ -155,8 +163,7 @@ always @(posedge sys_clk) begin
/* GPIO registers */
4'b0000: csr_do <= gpio_in;
4'b0001: csr_do <= gpio_outputs;
4'b0010: csr_do <= gpio_irqact;
4'b0011: csr_do <= gpio_irqen;
4'b0010: csr_do <= gpio_irqen;

/* Timer 0 registers */
4'b0100: csr_do <= {en0, ar0, trig0};
Expand Down
5 changes: 1 addition & 4 deletions software/demo/ui.c
Expand Up @@ -237,8 +237,7 @@ void ui_init()
for(i=1;i<KEY_COUNT;i++)
last_press[i] = last_press[0];

CSR_GPIO_CHANGES = UI_GPIO;
CSR_GPIO_INT |= UI_GPIO;
CSR_GPIO_INTEN |= UI_GPIO;

mask = irq_getmask();
mask |= IRQ_GPIO;
Expand Down Expand Up @@ -287,8 +286,6 @@ void ui_isr_key()
{
unsigned int keys;

CSR_GPIO_CHANGES = CSR_GPIO_CHANGES & UI_GPIO;

keys = CSR_GPIO_IN;

if(keys & GPIO_PBN)
Expand Down
3 changes: 1 addition & 2 deletions software/include/hw/sysctl.h
Expand Up @@ -22,8 +22,7 @@

#define CSR_GPIO_IN MMPTR(0x80001000)
#define CSR_GPIO_OUT MMPTR(0x80001004)
#define CSR_GPIO_CHANGES MMPTR(0x80001008)
#define CSR_GPIO_INT MMPTR(0x8000100C)
#define CSR_GPIO_INTEN MMPTR(0x80001008)

#define CSR_TIMER0_CONTROL MMPTR(0x80001010)
#define CSR_TIMER0_COMPARE MMPTR(0x80001014)
Expand Down
4 changes: 3 additions & 1 deletion software/libhal/pfpu.c
Expand Up @@ -35,7 +35,9 @@ void pfpu_init()
{
unsigned int mask;

CSR_PFPU_CTL = 0; /* Ack any pending IRQ */
/* Reset PFPU */
CSR_PFPU_CTL = 0;
irq_ack(IRQ_PFPU);

produce = 0;
consume = 0;
Expand Down
2 changes: 2 additions & 0 deletions software/libhal/ps2.c
Expand Up @@ -38,6 +38,8 @@ void ps2_init()
consume = 0;
level = 0;

irq_ack(IRQ_PS2);

mask = irq_getmask();
mask |= IRQ_PS2;
irq_setmask(mask);
Expand Down
8 changes: 4 additions & 4 deletions software/libhal/slowout.c
Expand Up @@ -47,7 +47,9 @@ void slowout_init()
level = 0;
cts = 1;

CSR_TIMER1_CONTROL = 0; /* Disable timer + ack any pending IRQ */
/* Reset timer */
CSR_TIMER1_CONTROL = 0;
irq_ack(IRQ_TIMER1);

mask = irq_getmask();
mask |= IRQ_TIMER1;
Expand All @@ -70,10 +72,8 @@ void slowout_isr()
level--;
if(level > 0)
slowout_start(&queue[consume]);
else {
CSR_TIMER1_CONTROL = 0; /* Ack IRQ */
else
cts = 1;
}
}

int slowout_queue(unsigned int duration, unsigned int mask)
Expand Down
4 changes: 4 additions & 0 deletions software/libhal/snd.c
Expand Up @@ -42,8 +42,12 @@ void snd_init()

snd_cr_request = 0;
snd_cr_reply = 0;

/* Reset AC'97 controller */
CSR_AC97_CRCTL = 0;
CSR_AC97_DCTL = 0;
CSR_AC97_UCTL = 0;
irq_ack(IRQ_AC97CRREQUEST|IRQ_AC97CRREPLY|IRQ_AC97DMAR|IRQ_AC97DMAW);

mask = irq_getmask();
mask |= IRQ_AC97CRREQUEST|IRQ_AC97CRREPLY|IRQ_AC97DMAR|IRQ_AC97DMAW;
Expand Down
2 changes: 1 addition & 1 deletion software/libhal/time.c
Expand Up @@ -35,6 +35,7 @@ void time_init()
CSR_TIMER0_COUNTER = 0;
CSR_TIMER0_COMPARE = brd_desc->clk_frequency;
CSR_TIMER0_CONTROL = TIMER_AUTORESTART|TIMER_ENABLE;
irq_ack(IRQ_TIMER0);

mask = irq_getmask();
mask |= IRQ_TIMER0;
Expand All @@ -46,7 +47,6 @@ void time_init()
void time_isr()
{
sec++;
CSR_TIMER0_CONTROL = TIMER_AUTORESTART|TIMER_ENABLE; /* Ack interrupt */
time_tick();
}

Expand Down
3 changes: 2 additions & 1 deletion software/libhal/tmu.c
Expand Up @@ -42,7 +42,8 @@ void tmu_init()
level = 0;
cts = 1;

CSR_TMU_CTL = 0; /* Ack any pending IRQ */
CSR_TMU_CTL = 0;
irq_ack(IRQ_TMU);

mask = irq_getmask();
mask |= IRQ_TMU;
Expand Down

0 comments on commit f02c2a7

Please sign in to comment.