diff --git a/hw/efinix_fpga/addr_decode.sv b/hw/efinix_fpga/addr_decode.sv index 43b1ed5..c304198 100644 --- a/hw/efinix_fpga/addr_decode.sv +++ b/hw/efinix_fpga/addr_decode.sv @@ -6,12 +6,14 @@ module addr_decode output o_leds_cs, output o_timer_cs, output o_multiplier_cs, + output o_divider_cs, output o_sdram_cs ); assign o_rom_cs = i_addr >= 16'hf000 && i_addr <= 16'hffff; assign o_timer_cs = i_addr >= 16'heff8 && i_addr <= 16'heffb; assign o_multiplier_cs = i_addr >= 16'heff0 && i_addr <= 16'heff7; +assign o_divider_cs = i_addr >= 16'hefe7 && i_addr <= 16'hefef; assign o_leds_cs = i_addr == 16'hefff; assign o_sdram_cs = i_addr < 16'h8000; diff --git a/hw/efinix_fpga/debug_profile.wizard.json b/hw/efinix_fpga/debug_profile.wizard.json index 65d6aa9..2232652 100644 --- a/hw/efinix_fpga/debug_profile.wizard.json +++ b/hw/efinix_fpga/debug_profile.wizard.json @@ -3,7 +3,7 @@ { "name": "la0", "type": "la", - "uuid": "aad3ac84df754229b9f34a0d7163d7ac", + "uuid": "60874ad57d6b45aaae3da20d2734bc20", "trigin_en": false, "trigout_en": false, "auto_inserted": true, @@ -31,35 +31,80 @@ "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 + }, + { + "name": "u_divider/rwb", + "width": 1, + "probe_type": 1 + }, + { + "name": "u_divider/rfd", + "width": 1, + "probe_type": 1 + }, + { + "name": "u_divider/reset", + "width": 1, + "probe_type": 1 + }, + { + "name": "u_divider/remain", + "width": 16, + "probe_type": 1 + }, + { + "name": "u_divider/quotient", + "width": 16, + "probe_type": 1 + }, + { + "name": "u_divider/o_data", + "width": 8, + "probe_type": 1 + }, + { + "name": "u_divider/numer", + "width": 16, + "probe_type": 1 + }, + { + "name": "u_divider/i_data", + "width": 8, + "probe_type": 1 + }, + { + "name": "u_divider/denom", + "width": 16, + "probe_type": 1 + }, + { + "name": "u_divider/cs", + "width": 1, + "probe_type": 1 + }, + { + "name": "u_divider/clken", + "width": 1, + "probe_type": 1 + }, + { + "name": "u_divider/clk", + "width": 1, + "probe_type": 1 + }, + { + "name": "u_divider/addr", + "width": 3, + "probe_type": 1 } ] } @@ -321,392 +366,672 @@ "path": [] }, { - "name": "la0_probe4", - "net": "count_en", - "path": [ - "u_timer" - ] - }, - { - "name": "la0_probe5[0]", + "name": "la0_probe4[0]", "net": "cpu_data_out[0]", "path": [] }, { - "name": "la0_probe5[1]", + "name": "la0_probe4[1]", "net": "cpu_data_out[1]", "path": [] }, { - "name": "la0_probe5[2]", + "name": "la0_probe4[2]", "net": "cpu_data_out[2]", "path": [] }, { - "name": "la0_probe5[3]", + "name": "la0_probe4[3]", "net": "cpu_data_out[3]", "path": [] }, { - "name": "la0_probe5[4]", + "name": "la0_probe4[4]", "net": "cpu_data_out[4]", "path": [] }, { - "name": "la0_probe5[5]", + "name": "la0_probe4[5]", "net": "cpu_data_out[5]", "path": [] }, { - "name": "la0_probe5[6]", + "name": "la0_probe4[6]", "net": "cpu_data_out[6]", "path": [] }, { - "name": "la0_probe5[7]", + "name": "la0_probe4[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", + "name": "la0_probe5", "net": "cpu_irqb", "path": [] + }, + { + "name": "la0_probe6", + "net": "rwb", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe7", + "net": "rfd", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe8", + "net": "reset", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe9[0]", + "net": "remain[0]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe9[1]", + "net": "remain[1]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe9[2]", + "net": "remain[2]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe9[3]", + "net": "remain[3]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe9[4]", + "net": "remain[4]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe9[5]", + "net": "remain[5]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe9[6]", + "net": "remain[6]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe9[7]", + "net": "remain[7]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe9[8]", + "net": "remain[8]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe9[9]", + "net": "remain[9]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe9[10]", + "net": "remain[10]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe9[11]", + "net": "remain[11]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe9[12]", + "net": "remain[12]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe9[13]", + "net": "remain[13]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe9[14]", + "net": "remain[14]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe9[15]", + "net": "remain[15]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe10[0]", + "net": "quotient[0]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe10[1]", + "net": "quotient[1]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe10[2]", + "net": "quotient[2]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe10[3]", + "net": "quotient[3]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe10[4]", + "net": "quotient[4]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe10[5]", + "net": "quotient[5]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe10[6]", + "net": "quotient[6]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe10[7]", + "net": "quotient[7]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe10[8]", + "net": "quotient[8]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe10[9]", + "net": "quotient[9]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe10[10]", + "net": "quotient[10]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe10[11]", + "net": "quotient[11]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe10[12]", + "net": "quotient[12]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe10[13]", + "net": "quotient[13]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe10[14]", + "net": "quotient[14]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe10[15]", + "net": "quotient[15]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe11[0]", + "net": "o_data[0]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe11[1]", + "net": "o_data[1]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe11[2]", + "net": "o_data[2]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe11[3]", + "net": "o_data[3]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe11[4]", + "net": "o_data[4]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe11[5]", + "net": "o_data[5]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe11[6]", + "net": "o_data[6]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe11[7]", + "net": "o_data[7]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe12[0]", + "net": "numer[0]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe12[1]", + "net": "numer[1]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe12[2]", + "net": "numer[2]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe12[3]", + "net": "numer[3]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe12[4]", + "net": "numer[4]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe12[5]", + "net": "numer[5]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe12[6]", + "net": "numer[6]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe12[7]", + "net": "numer[7]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe12[8]", + "net": "numer[8]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe12[9]", + "net": "numer[9]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe12[10]", + "net": "numer[10]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe12[11]", + "net": "numer[11]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe12[12]", + "net": "numer[12]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe12[13]", + "net": "numer[13]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe12[14]", + "net": "numer[14]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe12[15]", + "net": "numer[15]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe13[0]", + "net": "i_data[0]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe13[1]", + "net": "i_data[1]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe13[2]", + "net": "i_data[2]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe13[3]", + "net": "i_data[3]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe13[4]", + "net": "i_data[4]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe13[5]", + "net": "i_data[5]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe13[6]", + "net": "i_data[6]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe13[7]", + "net": "i_data[7]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe14[0]", + "net": "denom[0]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe14[1]", + "net": "denom[1]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe14[2]", + "net": "denom[2]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe14[3]", + "net": "denom[3]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe14[4]", + "net": "denom[4]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe14[5]", + "net": "denom[5]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe14[6]", + "net": "denom[6]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe14[7]", + "net": "denom[7]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe14[8]", + "net": "denom[8]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe14[9]", + "net": "denom[9]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe14[10]", + "net": "denom[10]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe14[11]", + "net": "denom[11]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe14[12]", + "net": "denom[12]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe14[13]", + "net": "denom[13]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe14[14]", + "net": "denom[14]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe14[15]", + "net": "denom[15]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe15", + "net": "cs", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe16", + "net": "clken", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe17", + "net": "clk", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe18[0]", + "net": "addr[0]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe18[1]", + "net": "addr[1]", + "path": [ + "u_divider" + ] + }, + { + "name": "la0_probe18[2]", + "net": "addr[2]", + "path": [ + "u_divider" + ] } ] } @@ -759,16 +1084,6 @@ "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, @@ -779,42 +1094,6 @@ "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, @@ -822,6 +1101,150 @@ "selected_probe_type": "DATA AND TRIGGER", "child": [], "path": [] + }, + { + "name": "rwb", + "width": 1, + "clk_domain": "clk_2", + "selected_probe_type": "DATA AND TRIGGER", + "child": [], + "path": [ + "u_divider" + ] + }, + { + "name": "rfd", + "width": 1, + "clk_domain": "clk_2", + "selected_probe_type": "DATA AND TRIGGER", + "child": [], + "path": [ + "u_divider" + ] + }, + { + "name": "reset", + "width": 1, + "clk_domain": "clk_2", + "selected_probe_type": "DATA AND TRIGGER", + "child": [], + "path": [ + "u_divider" + ] + }, + { + "name": "remain", + "width": 16, + "clk_domain": "clk_2", + "selected_probe_type": "DATA AND TRIGGER", + "child": [], + "path": [ + "u_divider" + ], + "net_idx_left": 15, + "net_idx_right": 0 + }, + { + "name": "quotient", + "width": 16, + "clk_domain": "clk_2", + "selected_probe_type": "DATA AND TRIGGER", + "child": [], + "path": [ + "u_divider" + ], + "net_idx_left": 15, + "net_idx_right": 0 + }, + { + "name": "o_data", + "width": 8, + "clk_domain": "clk_2", + "selected_probe_type": "DATA AND TRIGGER", + "child": [], + "path": [ + "u_divider" + ], + "net_idx_left": 7, + "net_idx_right": 0 + }, + { + "name": "numer", + "width": 16, + "clk_domain": "clk_2", + "selected_probe_type": "DATA AND TRIGGER", + "child": [], + "path": [ + "u_divider" + ], + "net_idx_left": 15, + "net_idx_right": 0 + }, + { + "name": "i_data", + "width": 8, + "clk_domain": "clk_2", + "selected_probe_type": "DATA AND TRIGGER", + "child": [], + "path": [ + "u_divider" + ], + "net_idx_left": 7, + "net_idx_right": 0 + }, + { + "name": "denom", + "width": 16, + "clk_domain": "clk_2", + "selected_probe_type": "DATA AND TRIGGER", + "child": [], + "path": [ + "u_divider" + ], + "net_idx_left": 15, + "net_idx_right": 0 + }, + { + "name": "cs", + "width": 1, + "clk_domain": "clk_2", + "selected_probe_type": "DATA AND TRIGGER", + "child": [], + "path": [ + "u_divider" + ] + }, + { + "name": "clken", + "width": 1, + "clk_domain": "clk_2", + "selected_probe_type": "DATA AND TRIGGER", + "child": [], + "path": [ + "u_divider" + ] + }, + { + "name": "clk", + "width": 1, + "clk_domain": "clk_2", + "selected_probe_type": "DATA AND TRIGGER", + "child": [], + "path": [ + "u_divider" + ] + }, + { + "name": "addr", + "width": 3, + "clk_domain": "clk_2", + "selected_probe_type": "DATA AND TRIGGER", + "child": [], + "path": [ + "u_divider" + ], + "net_idx_left": 2, + "net_idx_right": 0 } ], "top_module": "super6502", diff --git a/hw/efinix_fpga/divider_wrapper.sv b/hw/efinix_fpga/divider_wrapper.sv new file mode 100644 index 0000000..ef482ff --- /dev/null +++ b/hw/efinix_fpga/divider_wrapper.sv @@ -0,0 +1,82 @@ +module divider_wrapper( + input clk, + input reset, + input [7:0] i_data, + output logic [7:0] o_data, + input cs, + input rwb, + input [2:0] addr +); + +logic [15:0] numer, denom; +logic [15:0] quotient, remain; + +logic clken, rfd; + +assign clken = '1; + + +divider u_divider( +.numer ( numer ), +.denom ( denom ), +.clken ( clken ), +.clk ( clk ), +.reset ( reset ), +.quotient ( quotient ), +.remain ( remain ), +.rfd ( rfd ) +); + + +always_ff @(negedge clk) begin + if (reset) begin + numer <= '0; + denom <= '0; + end + + + if (cs & ~rwb) begin + case (addr) + 3'h0: begin + numer[7:0] <= i_data; + end + + 3'h1: begin + numer[15:8] <= i_data; + end + + 3'h2: begin + denom[7:0] <= i_data; + end + + 3'h3: begin + denom[15:8] <= i_data; + end + endcase + end +end + +always_comb begin + + case (addr) + 3'h4: begin + o_data = quotient[7:0]; + end + + 3'h5: begin + o_data = quotient[15:8]; + end + + 3'h6: begin + o_data = remain[7:0]; + end + + 3'h7: begin + o_data = remain[15:8]; + end + + endcase + +end + +endmodule \ No newline at end of file diff --git a/hw/efinix_fpga/ip/bram/bram_ini.vh b/hw/efinix_fpga/ip/bram/bram_ini.vh index f737621..a61bf89 100644 --- a/hw/efinix_fpga/ip/bram/bram_ini.vh +++ b/hw/efinix_fpga/ip/bram/bram_ini.vh @@ -4,8 +4,8 @@ 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'h008d000c8000a9000ef000f10008d00000000a9000ef000f00008d0007b000a9: -(val_== 1)?256'h0ef000ff0008d000ef000f5000ad000ef000f30008d00001000a9000ef000f20: +(val_== 0)?256'h008d0000d000a9000ef000e90008d00001000a9000ef000e80008d000c8000a9: +(val_== 1)?256'h0ef000ff0008d000ef000ec000ad000ef000eb0008d00000000a9000ef000ea0: (val_== 2)?256'h00000000000000000000000000000000000000000000000000e300080000cb00: (val_== 3)?256'h0000000000000000000000000000000000000000000000000000000000000000: (val_== 4)?256'h0000000000000000000000000000000000000000000000000000000000000000: diff --git a/hw/efinix_fpga/ip/bram/init_hex.mem b/hw/efinix_fpga/ip/bram/init_hex.mem index 05fb98d..58d6a4e 100644 --- a/hw/efinix_fpga/ip/bram/init_hex.mem +++ b/hw/efinix_fpga/ip/bram/init_hex.mem @@ -1,25 +1,25 @@ a9 -7b -8d -f0 -ef -a9 -00 -8d -f1 -ef -a9 c8 8d -f2 +e8 ef a9 01 8d -f3 +e9 +ef +a9 +0d +8d +ea +ef +a9 +00 +8d +eb ef ad -f5 +ec ef 8d ff diff --git a/hw/efinix_fpga/ip/divider/divider.v b/hw/efinix_fpga/ip/divider/divider.v new file mode 100644 index 0000000..7dc283a --- /dev/null +++ b/hw/efinix_fpga/ip/divider/divider.v @@ -0,0 +1,390 @@ +// ============================================================================= +// Generated by efx_ipmgr +// Version: 2022.2.322 +// IP Version: 2.2 +// ============================================================================= + +//////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2013-2022 Efinix Inc. All rights reserved. +// +// This document contains proprietary information which is +// protected by copyright. All rights are reserved. This notice +// refers to original work by Efinix, Inc. which may be derivitive +// of other work distributed under license of the authors. In the +// case of derivative work, nothing in this notice overrides the +// original author's license agreement. Where applicable, the +// original license agreement is included in it's original +// unmodified form immediately below this header. +// +// WARRANTY DISCLAIMER. +// THE DESIGN, CODE, OR INFORMATION ARE PROVIDED “AS IS” AND +// EFINIX MAKES NO WARRANTIES, EXPRESS OR IMPLIED WITH +// RESPECT THERETO, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES, +// INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR +// PURPOSE. SOME STATES DO NOT ALLOW EXCLUSIONS OF AN IMPLIED +// WARRANTY, SO THIS DISCLAIMER MAY NOT APPLY TO LICENSEE. +// +// LIMITATION OF LIABILITY. +// NOTWITHSTANDING ANYTHING TO THE CONTRARY, EXCEPT FOR BODILY +// INJURY, EFINIX SHALL NOT BE LIABLE WITH RESPECT TO ANY SUBJECT +// MATTER OF THIS AGREEMENT UNDER TORT, CONTRACT, STRICT LIABILITY +// OR ANY OTHER LEGAL OR EQUITABLE THEORY (I) FOR ANY INDIRECT, +// SPECIAL, INCIDENTAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES OF ANY +// CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF +// GOODWILL, DATA OR PROFIT, WORK STOPPAGE, OR COMPUTER FAILURE OR +// MALFUNCTION, OR IN ANY EVENT (II) FOR ANY AMOUNT IN EXCESS, IN +// THE AGGREGATE, OF THE FEE PAID BY LICENSEE TO EFINIX HEREUNDER +// (OR, IF THE FEE HAS BEEN WAIVED, $100), EVEN IF EFINIX SHALL HAVE +// BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO +// NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR +// CONSEQUENTIAL DAMAGES, SO THIS LIMITATION AND EXCLUSION MAY NOT +// APPLY TO LICENSEE. +// +//////////////////////////////////////////////////////////////////////////////// + +`define IP_UUID _1d82aa757d4b4554a855552eadc85243 +`define IP_NAME_CONCAT(a,b) a``b +`define IP_MODULE_NAME(name) `IP_NAME_CONCAT(name,`IP_UUID) +module divider ( +input [15:0] numer, +input [15:0] denom, +input clken, +input clk, +input reset, +output [15:0] quotient, +output [15:0] remain, +output rfd +); +`IP_MODULE_NAME(divider) #( +.NREPRESENTATION ("UNSIGNED"), +.WIDTHN (16), +.WIDTHD (16), +.DREPRESENTATION ("UNSIGNED"), +.PIPELINE (0), +.LATENCY (0) +) u_divider( +.numer ( numer ), +.denom ( denom ), +.clken ( clken ), +.clk ( clk ), +.reset ( reset ), +.quotient ( quotient ), +.remain ( remain ), +.rfd ( rfd ) +); + +endmodule + +`timescale 1ns / 1ps + +module `IP_MODULE_NAME(divider) ( + clk, + reset, + numer, + denom, + quotient, + remain, + rfd, + clken +); + +parameter WIDTHN = 8; +parameter WIDTHD = 8; +parameter LATENCY = 8; +parameter PIPELINE = 1; +parameter NREPRESENTATION = "UNSIGNED"; +parameter DREPRESENTATION = "UNSIGNED"; +parameter ENABLE_OUTREG = 0; + +input clk; +input reset; +input clken; +input [(WIDTHN-1):0] numer; +input [(WIDTHD-1):0] denom; +//output +output reg rfd; +output reg [(WIDTHN-1):0] quotient; +output reg [(WIDTHD-1):0] remain; + +wire [WIDTHN-1:0] numer_temp; +wire [WIDTHD-1:0] denom_temp; +wire sign_numer; +wire sign_denom; + +wire [(WIDTHN-1):0] quotient_copy; +wire [(WIDTHD-1):0] remain_copy; +reg sign_quotient[LATENCY:0]; + +genvar i, j; +// Main operation +generate begin + if(NREPRESENTATION == "SIGNED") begin + assign numer_temp = (numer[(WIDTHN-1)] == 1'b1) ? (~numer + 1) : numer; + assign sign_numer = (numer[(WIDTHN-1)] == 1'b1) ? 1'b1 : 1'b0; + end + else begin + assign numer_temp = numer; + assign sign_numer = 1'b0; + end + + if(DREPRESENTATION == "SIGNED") begin + assign denom_temp = (denom[(WIDTHD-1)] == 1'b1) ? (~denom + 1) : denom; + assign sign_denom = (denom[(WIDTHD-1)] == 1'b1) ? 1'b1 : 1'b0; + end + else begin + assign denom_temp = denom; + assign sign_denom = 1'b0; + end + + always @* begin + sign_quotient[0] = sign_numer ^ sign_denom; + end + + for (i=0; i 0) begin + reg [LATENCY-1:0] ready; + + assign sub = (ready[0] || ~clken_IP) ? ({{(WIDTHN-2){1'b0}}, numer_temp[(WIDTHN-1)]} - denom_sub) : ({remain_reg[(WIDTHN-2):0], quotient_reg[(WIDTHN-1)]} - denom_reg); + + always @(posedge clk,posedge reset) begin + if(reset) begin + ready <= {LATENCY{1'b0}}; + end + else if(clken) begin + if(ready[0] || ~clken_IP) begin + ready <= {1'b1, {LATENCY-1{1'b0}}}; + end + else begin + ready <= {1'b0, ready[LATENCY-1:1]}; + end + end + else begin + ready <= {LATENCY{1'b0}}; + end + end + + always @(posedge clk,posedge reset) begin + if(reset) begin + remain_reg <= {WIDTHN{1'b0}}; + quotient_reg <= {WIDTHN{1'b0}}; + denom_reg <= {WIDTHN{1'b0}}; + end + else if(clken) begin + if(ready[0] || ~clken_IP) begin + denom_reg <= denom_temp; + if (sub[(WIDTHN)] == 0) begin + remain_reg <= sub[(WIDTHN-1):0]; + quotient_reg <= {numer_temp[(WIDTHN-2):0], 1'b1}; + end + else begin + remain_reg <= {{(WIDTHN-2){1'b0}}, numer_temp[(WIDTHN-1)]}; + quotient_reg <= {numer_temp[(WIDTHN-2):0], 1'b0}; + end + end + else begin + if (sub[(WIDTHN)] == 0) begin + remain_reg <= sub[(WIDTHN-1):0]; + quotient_reg <= {quotient_reg[(WIDTHN-2):0], 1'b1}; + end + else begin + remain_reg <= {remain_reg[(WIDTHN-2):0], quotient_reg[(WIDTHN-1)]}; + quotient_reg <= {quotient_reg[(WIDTHN-2):0], 1'b0}; + end + end + end + end + + if (ENABLE_OUTREG) begin + always @(posedge clk,posedge reset) begin + if (reset) begin + rfd <= 1'b0; + end + else begin + rfd <= ready[0]; + end + end + end + else begin + always @* begin + rfd = ready[0]; + end + end + + always @* begin + quotient_combi[0] = quotient_reg; + remain_combi[0] = remain_reg; + end + + for (i=0; i numer, +denom => denom, +clken => clken, +clk => clk, +reset => reset, +quotient => quotient, +remain => remain, +rfd => rfd); +------------------------ End INSTANTIATION Template --------- diff --git a/hw/efinix_fpga/ip/divider/settings.json b/hw/efinix_fpga/ip/divider/settings.json new file mode 100644 index 0000000..cfe9d25 --- /dev/null +++ b/hw/efinix_fpga/ip/divider/settings.json @@ -0,0 +1,33 @@ +{ + "args": [ + "-o", + "divider", + "--base_path", + "/home/byron/Projects/super6502/hw/efinix_fpga/ip", + "--vlnv", + { + "vendor": "efinixinc.com", + "library": "arithmetic", + "name": "efx_divider", + "version": "2.2" + } + ], + "conf": { + "NREPRESENTATION": "0", + "WIDTHN": "16", + "WIDTHD": "16", + "DREPRESENTATION": "0", + "PIPELINE": "0", + "LATENCY": "0" + }, + "output": { + "external_source_source": [ + "/home/byron/Projects/super6502/hw/efinix_fpga/ip/divider/divider.v", + "/home/byron/Projects/super6502/hw/efinix_fpga/ip/divider/divider_define.vh", + "/home/byron/Projects/super6502/hw/efinix_fpga/ip/divider/divider_tmpl.vhd", + "/home/byron/Projects/super6502/hw/efinix_fpga/ip/divider/divider_tmpl.v" + ] + }, + "sw_version": "2022.2.322", + "generated_date": "2023-01-05T22:36:48.178317" +} \ No newline at end of file diff --git a/hw/efinix_fpga/super6502.sv b/hw/efinix_fpga/super6502.sv index 5c95ee1..411ba79 100644 --- a/hw/efinix_fpga/super6502.sv +++ b/hw/efinix_fpga/super6502.sv @@ -67,6 +67,7 @@ logic w_leds_cs; logic w_sdram_cs; logic w_timer_cs; logic w_multiplier_cs; +logic w_divider_cs; addr_decode u_addr_decode( .i_addr(cpu_addr), @@ -74,6 +75,7 @@ addr_decode u_addr_decode( .o_leds_cs(w_leds_cs), .o_timer_cs(w_timer_cs), .o_multiplier_cs(w_multiplier_cs), + .o_divider_cs(w_divider_cs), .o_sdram_cs(w_sdram_cs) ); @@ -81,6 +83,7 @@ logic [7:0] w_rom_data_out; logic [7:0] w_leds_data_out; logic [7:0] w_timer_data_out; logic [7:0] w_multiplier_data_out; +logic [7:0] w_divider_data_out; logic [7:0] w_sdram_data_out; always_comb begin @@ -92,6 +95,8 @@ always_comb begin cpu_data_out = w_timer_data_out; else if (w_multiplier_cs) cpu_data_out = w_multiplier_data_out; + else if (w_divider_cs) + cpu_data_out = w_divider_data_out; else if (w_sdram_cs) cpu_data_out = w_sdram_data_out; else @@ -142,6 +147,16 @@ multiplier u_multiplier( .addr(cpu_addr[2:0]) ); +divider_wrapper u_divider( + .clk(clk_2), + .reset(~cpu_resb), + .i_data(cpu_data_in), + .o_data(w_divider_data_out), + .cs(w_divider_cs), + .rwb(cpu_rwb), + .addr(cpu_addr[2:0]) +); + sdram_adapter u_sdram_adapter( .i_cpuclk(clk_2), .i_arst(~button_reset), diff --git a/hw/efinix_fpga/super6502.xml b/hw/efinix_fpga/super6502.xml index 57982b6..0488b34 100644 --- a/hw/efinix_fpga/super6502.xml +++ b/hw/efinix_fpga/super6502.xml @@ -1,5 +1,5 @@ - + @@ -19,6 +19,7 @@ + @@ -31,6 +32,9 @@ + + + @@ -55,8 +59,9 @@ - + + @@ -89,7 +94,7 @@ - + diff --git a/hw/efinix_fpga/test_programs/Makefile b/hw/efinix_fpga/test_programs/Makefile index 8e7490b..331ad32 100644 --- a/hw/efinix_fpga/test_programs/Makefile +++ b/hw/efinix_fpga/test_programs/Makefile @@ -1,4 +1,4 @@ -TARGETS=stacktest runram timer timer_irq multiplier +TARGETS=stacktest runram timer timer_irq multiplier divider SRC=$(wildcard *.s) DIR=../ip/bram diff --git a/hw/efinix_fpga/test_programs/divider.s b/hw/efinix_fpga/test_programs/divider.s new file mode 100644 index 0000000..df27127 --- /dev/null +++ b/hw/efinix_fpga/test_programs/divider.s @@ -0,0 +1,33 @@ +.code + +LEDS = $efff + +DIVNL = $efe8 +DIVNH = $efe9 +DIVDL = $efea +DIVDH = $efeb + +DIVQL = $efec +DIVQH = $efed +DIVRL = $efee +DIVRH = $efef + +main: + lda #$c8 + sta DIVNL + lda #$01 + sta DIVNH + lda #$0d + sta DIVDL + lda #$00 + sta DIVDH + lda DIVQL + sta LEDS + wai + bra main + +.segment "VECTORS" + +.addr main +.addr main +.addr main \ No newline at end of file