Add interrupt based timer and test code
This commit is contained in:
@@ -10,7 +10,7 @@ module addr_decode
|
||||
|
||||
assign o_rom_cs = i_addr >= 16'hf000 && i_addr <= 16'hffff;
|
||||
assign o_leds_cs = i_addr == 16'hefff;
|
||||
assign o_timer_cs = i_addr >= 16'heff8 && i_addr <= 16'heffe;
|
||||
assign o_timer_cs = i_addr >= 16'heff8 && i_addr <= 16'heffb;
|
||||
assign o_sdram_cs = i_addr < 16'h8000;
|
||||
|
||||
endmodule
|
||||
@@ -3,7 +3,7 @@
|
||||
{
|
||||
"name": "la0",
|
||||
"type": "la",
|
||||
"uuid": "eca5777d2e5a40ed85ba29fd5435f87f",
|
||||
"uuid": "281a52604f2c437c9bde96b89d672260",
|
||||
"trigin_en": false,
|
||||
"trigout_en": false,
|
||||
"auto_inserted": true,
|
||||
@@ -30,6 +30,36 @@
|
||||
"name": "cpu_sync",
|
||||
"width": 1,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "u_timer/count_en",
|
||||
"width": 1,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "cpu_data_out",
|
||||
"width": 8,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "u_timer/timer_latch",
|
||||
"width": 16,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "u_timer/pulsecount",
|
||||
"width": 16,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "u_timer/timer_counter",
|
||||
"width": 16,
|
||||
"probe_type": 1
|
||||
},
|
||||
{
|
||||
"name": "cpu_irqb",
|
||||
"width": 1,
|
||||
"probe_type": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -289,6 +319,394 @@
|
||||
"name": "la0_probe3",
|
||||
"net": "cpu_sync",
|
||||
"path": []
|
||||
},
|
||||
{
|
||||
"name": "la0_probe4",
|
||||
"net": "count_en",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe5[0]",
|
||||
"net": "cpu_data_out[0]",
|
||||
"path": []
|
||||
},
|
||||
{
|
||||
"name": "la0_probe5[1]",
|
||||
"net": "cpu_data_out[1]",
|
||||
"path": []
|
||||
},
|
||||
{
|
||||
"name": "la0_probe5[2]",
|
||||
"net": "cpu_data_out[2]",
|
||||
"path": []
|
||||
},
|
||||
{
|
||||
"name": "la0_probe5[3]",
|
||||
"net": "cpu_data_out[3]",
|
||||
"path": []
|
||||
},
|
||||
{
|
||||
"name": "la0_probe5[4]",
|
||||
"net": "cpu_data_out[4]",
|
||||
"path": []
|
||||
},
|
||||
{
|
||||
"name": "la0_probe5[5]",
|
||||
"net": "cpu_data_out[5]",
|
||||
"path": []
|
||||
},
|
||||
{
|
||||
"name": "la0_probe5[6]",
|
||||
"net": "cpu_data_out[6]",
|
||||
"path": []
|
||||
},
|
||||
{
|
||||
"name": "la0_probe5[7]",
|
||||
"net": "cpu_data_out[7]",
|
||||
"path": []
|
||||
},
|
||||
{
|
||||
"name": "la0_probe6[0]",
|
||||
"net": "timer_latch[0]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe6[1]",
|
||||
"net": "timer_latch[1]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe6[2]",
|
||||
"net": "timer_latch[2]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe6[3]",
|
||||
"net": "timer_latch[3]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe6[4]",
|
||||
"net": "timer_latch[4]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe6[5]",
|
||||
"net": "timer_latch[5]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe6[6]",
|
||||
"net": "timer_latch[6]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe6[7]",
|
||||
"net": "timer_latch[7]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe6[8]",
|
||||
"net": "timer_latch[8]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe6[9]",
|
||||
"net": "timer_latch[9]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe6[10]",
|
||||
"net": "timer_latch[10]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe6[11]",
|
||||
"net": "timer_latch[11]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe6[12]",
|
||||
"net": "timer_latch[12]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe6[13]",
|
||||
"net": "timer_latch[13]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe6[14]",
|
||||
"net": "timer_latch[14]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe6[15]",
|
||||
"net": "timer_latch[15]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe7[0]",
|
||||
"net": "pulsecount[0]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe7[1]",
|
||||
"net": "pulsecount[1]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe7[2]",
|
||||
"net": "pulsecount[2]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe7[3]",
|
||||
"net": "pulsecount[3]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe7[4]",
|
||||
"net": "pulsecount[4]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe7[5]",
|
||||
"net": "pulsecount[5]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe7[6]",
|
||||
"net": "pulsecount[6]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe7[7]",
|
||||
"net": "pulsecount[7]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe7[8]",
|
||||
"net": "pulsecount[8]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe7[9]",
|
||||
"net": "pulsecount[9]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe7[10]",
|
||||
"net": "pulsecount[10]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe7[11]",
|
||||
"net": "pulsecount[11]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe7[12]",
|
||||
"net": "pulsecount[12]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe7[13]",
|
||||
"net": "pulsecount[13]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe7[14]",
|
||||
"net": "pulsecount[14]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe7[15]",
|
||||
"net": "pulsecount[15]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe8[0]",
|
||||
"net": "timer_counter[0]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe8[1]",
|
||||
"net": "timer_counter[1]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe8[2]",
|
||||
"net": "timer_counter[2]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe8[3]",
|
||||
"net": "timer_counter[3]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe8[4]",
|
||||
"net": "timer_counter[4]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe8[5]",
|
||||
"net": "timer_counter[5]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe8[6]",
|
||||
"net": "timer_counter[6]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe8[7]",
|
||||
"net": "timer_counter[7]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe8[8]",
|
||||
"net": "timer_counter[8]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe8[9]",
|
||||
"net": "timer_counter[9]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe8[10]",
|
||||
"net": "timer_counter[10]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe8[11]",
|
||||
"net": "timer_counter[11]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe8[12]",
|
||||
"net": "timer_counter[12]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe8[13]",
|
||||
"net": "timer_counter[13]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe8[14]",
|
||||
"net": "timer_counter[14]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe8[15]",
|
||||
"net": "timer_counter[15]",
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "la0_probe9",
|
||||
"net": "cpu_irqb",
|
||||
"path": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -340,6 +758,70 @@
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": []
|
||||
},
|
||||
{
|
||||
"name": "count_en",
|
||||
"width": 1,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [
|
||||
"u_timer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "cpu_data_out",
|
||||
"width": 8,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [],
|
||||
"net_idx_left": 7,
|
||||
"net_idx_right": 0
|
||||
},
|
||||
{
|
||||
"name": "timer_latch",
|
||||
"width": 16,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [
|
||||
"u_timer"
|
||||
],
|
||||
"net_idx_left": 15,
|
||||
"net_idx_right": 0
|
||||
},
|
||||
{
|
||||
"name": "pulsecount",
|
||||
"width": 16,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [
|
||||
"u_timer"
|
||||
],
|
||||
"net_idx_left": 15,
|
||||
"net_idx_right": 0
|
||||
},
|
||||
{
|
||||
"name": "timer_counter",
|
||||
"width": 16,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": [
|
||||
"u_timer"
|
||||
],
|
||||
"net_idx_left": 15,
|
||||
"net_idx_right": 0
|
||||
},
|
||||
{
|
||||
"name": "cpu_irqb",
|
||||
"width": 1,
|
||||
"clk_domain": "clk_2",
|
||||
"selected_probe_type": "DATA AND TRIGGER",
|
||||
"child": [],
|
||||
"path": []
|
||||
}
|
||||
],
|
||||
"top_module": "super6502",
|
||||
|
||||
@@ -4,9 +4,9 @@ input integer index;//Mode type
|
||||
input integer val_; //Port A index, Port B Index, Number of Items in Loop, Port A Start, Port B Start, reserved
|
||||
case (index)
|
||||
0: bram_ini_table=
|
||||
(val_== 0)?256'h00ef000ff0009c0001000085000ef000f8000ad000ef000fd0008d000ff000a9:
|
||||
(val_== 1)?256'h086000f40009000020000e90003800010000e500038000aa000ef000f8000ad0:
|
||||
(val_== 2)?256'h00000000000000000000000000000000000ed00080000ef000ff000ee0001000:
|
||||
(val_== 0)?256'h008d00000000a9000ef000fb0008d00001000a9000ef000fa0008d000ff000a9:
|
||||
(val_== 1)?256'h0f8000ad000fd00080000cb00058000ef000f80008d00010000a9000ef000f90:
|
||||
(val_== 2)?256'h000000000000000000000000000000000000000040000ef000ff000ee000ef00:
|
||||
(val_== 3)?256'h0000000000000000000000000000000000000000000000000000000000000000:
|
||||
(val_== 4)?256'h0000000000000000000000000000000000000000000000000000000000000000:
|
||||
(val_== 5)?256'h0000000000000000000000000000000000000000000000000000000000000000:
|
||||
@@ -23,7 +23,7 @@ case (index)
|
||||
(val_==16)?256'h0000000000000000000000000000000000000000000000000000000000000000:
|
||||
(val_==17)?256'h0000000000000000000000000000000000000000000000000000000000000000:
|
||||
(val_==18)?256'h0000000000000000000000000000000000000000000000000000000000000000:
|
||||
(val_==19)?256'h000ff00000000ff00000000ff000000000000000000000000000000000000000:
|
||||
(val_==19)?256'h000ff00018000ff00000000ff000000000000000000000000000000000000000:
|
||||
(val_==20)?256'h0000000000000000000000000000000000000000000000000000000000000000:
|
||||
(val_==21)?256'h0000000000000000000000000000000000000000000000000000000000000000:
|
||||
(val_==22)?256'h0000000000000000000000000000000000000000000000000000000000000000:
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
a9
|
||||
ff
|
||||
8d
|
||||
fa
|
||||
ef
|
||||
a9
|
||||
01
|
||||
8d
|
||||
fb
|
||||
ef
|
||||
a9
|
||||
00
|
||||
8d
|
||||
f9
|
||||
ef
|
||||
a9
|
||||
10
|
||||
8d
|
||||
f8
|
||||
ef
|
||||
58
|
||||
cb
|
||||
80
|
||||
fd
|
||||
ef
|
||||
ad
|
||||
f8
|
||||
ef
|
||||
85
|
||||
10
|
||||
9c
|
||||
ff
|
||||
ef
|
||||
ad
|
||||
f8
|
||||
ef
|
||||
aa
|
||||
38
|
||||
e5
|
||||
10
|
||||
38
|
||||
e9
|
||||
20
|
||||
90
|
||||
f4
|
||||
86
|
||||
10
|
||||
ee
|
||||
ff
|
||||
ef
|
||||
80
|
||||
ed
|
||||
40
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
@@ -252,5 +252,5 @@ ed
|
||||
ff
|
||||
00
|
||||
ff
|
||||
00
|
||||
18
|
||||
ff
|
||||
|
||||
@@ -114,7 +114,7 @@ leds u_leds(
|
||||
.o_leds(leds)
|
||||
);
|
||||
|
||||
logic w_timer_irq;
|
||||
logic w_timer_irqb;
|
||||
|
||||
timer u_timer(
|
||||
.clk(clk_2),
|
||||
@@ -123,8 +123,8 @@ timer u_timer(
|
||||
.o_data(w_timer_data_out),
|
||||
.cs(w_timer_cs),
|
||||
.rwb(cpu_rwb),
|
||||
.addr(cpu_addr[2:0]),
|
||||
.irq(w_timer_irq)
|
||||
.addr(cpu_addr[1:0]),
|
||||
.irqb(w_timer_irqb)
|
||||
);
|
||||
|
||||
sdram_adapter u_sdram_adapter(
|
||||
@@ -164,7 +164,7 @@ interrupt_controller u_interrupt_controller(
|
||||
.cs(w_irq_cs),
|
||||
.rwb(cpu_rwb),
|
||||
.irqb_master(cpu_irqb),
|
||||
.irqb0(w_timer_irq),
|
||||
.irqb0(w_timer_irqb),
|
||||
.irqb1('1),
|
||||
.irqb2('1),
|
||||
.irqb3('1),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<efx:project name="super6502" description="" last_change_date="Tue January 3 2023 15:48:31" location="/home/byron/Projects/super6502/hw/efinix_fpga" sw_version="2022.2.322" last_run_state="pass" last_run_tool="efx_pgm" last_run_flow="bitstream" config_result_in_sync="true" design_ood="sync" place_ood="sync" route_ood="sync" xmlns:efx="http://www.efinixinc.com/enf_proj" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.efinixinc.com/enf_proj enf_proj.xsd">
|
||||
<efx:project name="super6502" description="" last_change_date="Tue January 3 2023 18:18:26" location="/home/byron/Projects/super6502/hw/efinix_fpga" sw_version="2022.2.322" last_run_state="pass" last_run_tool="efx_pgm" last_run_flow="bitstream" config_result_in_sync="true" design_ood="sync" place_ood="sync" route_ood="sync" xmlns:efx="http://www.efinixinc.com/enf_proj" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.efinixinc.com/enf_proj enf_proj.xsd">
|
||||
<efx:device_info>
|
||||
<efx:family name="Trion"/>
|
||||
<efx:device name="T20F256"/>
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
TARGETS=stacktest runram timer
|
||||
TARGETS=stacktest runram timer timer_irq
|
||||
SRC=$(wildcard *.s)
|
||||
DIR=../ip/bram
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
$(TARGETS):
|
||||
$(TARGETS): $(SRC)
|
||||
cl65 --cpu 65c02 -C link.ld -l $@.list $@.s
|
||||
xxd -ps $@ | fold -w 2 > $@.hex
|
||||
|
||||
install:
|
||||
cp $(TARGET).hex $(DIR)/init_hex.mem
|
||||
cd $(DIR);python3 efx_mem_init_script.py hex init_hex.mem
|
||||
|
||||
|
||||
clean:
|
||||
rm -f $(TARGETS)
|
||||
rm *.hex
|
||||
|
||||
@@ -2,13 +2,21 @@
|
||||
|
||||
LEDS = $efff
|
||||
TIMER_BASE = $eff8
|
||||
TIMER_DIVISOR = 5
|
||||
|
||||
TIMER_DIVISOR = 2
|
||||
TIMER_CL = 0
|
||||
TIMER_LL = 0
|
||||
TIMER_CH = 1
|
||||
TIMER_LH = 1
|
||||
TIMER_STATUS = 3
|
||||
TIMER_OLD = $10
|
||||
|
||||
main:
|
||||
lda #$ff
|
||||
lda #$01
|
||||
sta TIMER_BASE+TIMER_DIVISOR
|
||||
lda #$00
|
||||
sta TIMER_BASE+TIMER_LH
|
||||
lda #$0F
|
||||
sta TIMER_BASE+TIMER_LL
|
||||
lda TIMER_BASE
|
||||
sta TIMER_OLD
|
||||
stz LEDS
|
||||
|
||||
39
hw/efinix_fpga/test_programs/timer_irq.s
Normal file
39
hw/efinix_fpga/test_programs/timer_irq.s
Normal file
@@ -0,0 +1,39 @@
|
||||
.code
|
||||
|
||||
LEDS = $efff
|
||||
TIMER_BASE = $eff8
|
||||
TIMER_DIVISOR = 2
|
||||
TIMER_CL = 0
|
||||
TIMER_LL = 0
|
||||
TIMER_CH = 1
|
||||
TIMER_LH = 1
|
||||
TIMER_STATUS = 3
|
||||
TIMER_CONTROL = 3
|
||||
TIMER_OLD = $10
|
||||
|
||||
main:
|
||||
lda #$ff
|
||||
sta TIMER_BASE+TIMER_DIVISOR
|
||||
lda #$01
|
||||
sta TIMER_BASE+TIMER_CONTROL
|
||||
lda #$00
|
||||
sta TIMER_BASE+TIMER_LH
|
||||
lda #$10
|
||||
sta TIMER_BASE+TIMER_LL
|
||||
cli
|
||||
|
||||
loop:
|
||||
wai
|
||||
bra loop
|
||||
|
||||
irq:
|
||||
lda TIMER_BASE
|
||||
inc LEDS
|
||||
rti
|
||||
|
||||
|
||||
.segment "VECTORS"
|
||||
|
||||
.addr main
|
||||
.addr main
|
||||
.addr irq
|
||||
@@ -6,8 +6,8 @@ module timer
|
||||
output logic [7:0] o_data,
|
||||
input cs,
|
||||
input rwb,
|
||||
input [2:0] addr,
|
||||
output logic irq
|
||||
input [1:0] addr,
|
||||
output logic irqb
|
||||
);
|
||||
|
||||
//new idea for timer:
|
||||
@@ -15,43 +15,88 @@ module timer
|
||||
//it can either cause an interrupt or not.
|
||||
//if you want it to do both, add another timer.
|
||||
|
||||
/*
|
||||
Addr Read Write
|
||||
0 Counter Low Latch Low
|
||||
1 Counter High Latch High
|
||||
2 Divisor Divisor
|
||||
3 Status Control
|
||||
*/
|
||||
|
||||
logic [15:0] timer_latch, timer_counter;
|
||||
|
||||
//control register
|
||||
// bit 0: Enable interrupts
|
||||
// bit 1: Enable 1 shot mode
|
||||
|
||||
//by default it just starts counting up
|
||||
//writing to latch low starts the timer
|
||||
|
||||
logic [7:0] divisor, status, control;
|
||||
|
||||
logic count_en;
|
||||
|
||||
assign status[0] = count_en;
|
||||
|
||||
logic [15:0] pulsecount;
|
||||
|
||||
//I think this should be negedge so that writes go through
|
||||
always @(negedge clk) begin
|
||||
if (reset) begin
|
||||
count_en = '0;
|
||||
timer_counter <= '0;
|
||||
pulsecount <= '0;
|
||||
timer_latch <= '0;
|
||||
timer_latch <= '1;
|
||||
divisor <= '0;
|
||||
status <= '0;
|
||||
control <= '0;
|
||||
irq <= '1;
|
||||
irqb <= '1;
|
||||
end else begin
|
||||
|
||||
if (pulsecount[15:8] == divisor) begin
|
||||
timer_counter <= timer_counter + 16'b1;
|
||||
pulsecount <= '0;
|
||||
end else begin
|
||||
pulsecount <= pulsecount + 16'b1;
|
||||
if (count_en) begin
|
||||
if (pulsecount[15:8] == divisor) begin
|
||||
timer_counter <= timer_counter + 16'b1;
|
||||
pulsecount <= '0;
|
||||
end else begin
|
||||
pulsecount <= pulsecount + 16'b1;
|
||||
end
|
||||
end
|
||||
|
||||
if (timer_counter == timer_latch) begin
|
||||
// if interrupts are enabled
|
||||
if (control[0]) begin
|
||||
irqb <= '0;
|
||||
end
|
||||
|
||||
// if oneshot mode is enabled
|
||||
if (control[1]) begin
|
||||
count_en <= '0;
|
||||
end else begin
|
||||
timer_counter <= '0;
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if (cs & rwb) begin
|
||||
irqb <= '1;
|
||||
end
|
||||
|
||||
if (cs & ~rwb) begin
|
||||
case (addr)
|
||||
3'h5: begin
|
||||
2'h0: begin
|
||||
count_en <= '1;
|
||||
timer_latch[7:0] <= i_data;
|
||||
end
|
||||
|
||||
2'h1: begin
|
||||
timer_latch[15:8] <= i_data;
|
||||
end
|
||||
|
||||
2'h2: begin
|
||||
divisor <= i_data;
|
||||
end
|
||||
|
||||
2'h3: begin
|
||||
control <= i_data;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
@@ -62,36 +107,20 @@ always_comb begin
|
||||
o_data = '0;
|
||||
|
||||
unique case (addr)
|
||||
3'h0: begin
|
||||
2'h0: begin
|
||||
o_data = timer_counter[7:0];
|
||||
end
|
||||
|
||||
3'h1: begin
|
||||
2'h1: begin
|
||||
o_data = timer_counter[15:8];
|
||||
end
|
||||
|
||||
3'h2: begin
|
||||
|
||||
2'h2: begin
|
||||
o_data = divisor;
|
||||
end
|
||||
|
||||
3'h3: begin
|
||||
|
||||
end
|
||||
|
||||
3'h4: begin
|
||||
|
||||
end
|
||||
|
||||
3'h5: begin
|
||||
|
||||
end
|
||||
|
||||
3'h6: begin
|
||||
|
||||
end
|
||||
|
||||
3'h7: begin
|
||||
|
||||
2'h3: begin
|
||||
o_data = status;
|
||||
end
|
||||
|
||||
endcase
|
||||
|
||||
Reference in New Issue
Block a user