1
0
mirror of https://github.com/UzixLS/zx-sizif-xxs.git synced 2025-07-19 07:11:28 +03:00

initial add fpga sources

This commit is contained in:
UzixLS
2021-05-02 21:49:00 +03:00
parent 2edde64a92
commit 1888a76d79
29 changed files with 5758 additions and 0 deletions

149
fpga/rtl/chroma_gen.v Executable file
View File

@ -0,0 +1,149 @@
// Based on Joerg Wolfram's code //
module chroma_gen #(
parameter CLK_FREQ
) (
input cg_clock, // input clock
input cg_enable, // colour enable
input cg_hsync, // hor. sync
input cg_pnsel, // system (pal/ntsc)
input [2:0] cg_rgb, // rgb input
output reg [2:0] cg_out // chroma out
);
localparam CARRIER_WIDTH =
(CLK_FREQ == 14_000_000)? 17 :
(CLK_FREQ == 14_318_180)? 17 :
(CLK_FREQ == 16_000_000)? 14 :
(CLK_FREQ == 17_734_475)? 3 :
(CLK_FREQ == 20_000_000)? 14 :
(CLK_FREQ == 24_000_000)? 17 :
(CLK_FREQ == 25_000_000)? 16 :
(CLK_FREQ == 28_000_000)? 18 :
(CLK_FREQ == 28_375_000)? 16 :
(CLK_FREQ == 28_636_360)? 18 :
(CLK_FREQ == 32_000_000)? 15 :
(CLK_FREQ == 35_468_950)? 3 :
(CLK_FREQ == 40_000_000)? 15 :
0;
localparam PAL_CARRIER =
(CLK_FREQ == 14_000_000)? 83018 : // 20.776 error
(CLK_FREQ == 14_318_180)? 81173 : // 11.72 error
(CLK_FREQ == 16_000_000)? 9080 : // 25 error
(CLK_FREQ == 17_734_475)? 4 : // 0 error
(CLK_FREQ == 20_000_000)? 7264 : // 25 error
(CLK_FREQ == 24_000_000)? 48427 : // 5.51 error
(CLK_FREQ == 25_000_000)? 23245 : // 13.14 error
(CLK_FREQ == 28_000_000)? 83018 : // 20.78 error
(CLK_FREQ == 28_375_000)? 20480 : // 25 error
(CLK_FREQ == 28_636_360)? 81173 : // 11.76 error
(CLK_FREQ == 32_000_000)? 9080 : // 25 error
(CLK_FREQ == 35_468_950)? 2 : // 0 error
(CLK_FREQ == 40_000_000)? 7264 : // 25 error
0;
localparam NTSC_CARRIER =
(CLK_FREQ == 14_000_000)? 67025 : // 23.82 error
(CLK_FREQ == 14_318_180)? 65536 : // 0 errror
(CLK_FREQ == 16_000_000)? 7331 : // 44.84 error
(CLK_FREQ == 17_734_475)? 4 : // 0 error (NTSC4.43)
(CLK_FREQ == 20_000_000)? 5865 : // 166.91 error
(CLK_FREQ == 24_000_000)? 39098 : // 16.19 error
(CLK_FREQ == 25_000_000)? 18767 : // 23.82 error
(CLK_FREQ == 28_000_000)? 67025 : // 23.82 error
(CLK_FREQ == 28_375_000)? 16535 : // 19.1 error
(CLK_FREQ == 28_636_360)? 65536 : // 0 error
(CLK_FREQ == 32_000_000)? 7331 : // 44.84 error
(CLK_FREQ == 35_468_950)? 2 : // 0 error (NTSC4.43)
(CLK_FREQ == 40_000_000)? 5865 : // 166.91 error
0;
// localparam PAL_CARRIER = 64'd17_734_475 * (1<<(CARRIER_WIDTH-1)) / CLK_FREQ;
// localparam NTSC_CARRIER = 64'd14_318_180 * (1<<(CARRIER_WIDTH-1)) / CLK_FREQ;
reg [CARRIER_WIDTH:0] carrier;
wire [31:0] carrier_next;
reg [3:0] burst_cnt;
wire burst;
reg oddeven;
reg [3:0] phase;
reg [3:0] scarrier;
wire cenable;
// DDS for PAL-carrier
assign carrier_next = (cg_pnsel == 1'b0)?
(carrier + PAL_CARRIER) :
(carrier + NTSC_CARRIER) ;
always @(posedge cg_clock) begin
carrier <= carrier_next[CARRIER_WIDTH:0];
end
// burst generator
always @(posedge carrier[CARRIER_WIDTH] or negedge cg_hsync) begin
if (cg_hsync == 1'b0)
burst_cnt <= 4'b0100;
else if (burst_cnt != 4'b0000)
burst_cnt <= burst_cnt + 1'b1;
end
assign burst = burst_cnt[3];
// odd/even line
always @(posedge cg_hsync) begin
if (cg_pnsel == 1'b0)
oddeven <= ~oddeven;
else
oddeven <= 1'b0;
end
// carrier phase
always @* begin
if (burst == 1'b1) begin
if ((oddeven == 1'b0) && (cg_pnsel == 1'b0))
phase <= 4'b0110; // burst phase 135 deg
else
phase <= 4'b1010; // burst phase -135 deg
end
else if (oddeven == 1'b0) begin
case (cg_rgb)
3'b001: phase <= 4'b0000; // blue phase
3'b010: phase <= 4'b0101; // red phase
3'b011: phase <= 4'b0011; // magenta phase
3'b100: phase <= 4'b1011; // green phase
3'b101: phase <= 4'b1101; // cyan phase
3'b110: phase <= 4'b0111; // yellow phase
default: phase <= 4'b0000; // dummy function
endcase
end
else begin
case (cg_rgb)
3'b001: phase <= 4'b0000; // blue phase
3'b010: phase <= 4'b1011; // red phase
3'b011: phase <= 4'b1101; // magenta phase
3'b100: phase <= 4'b0101; // green phase
3'b101: phase <= 4'b0011; // cyan phase
3'b110: phase <= 4'b1001; // yellow phase
default: phase <= 4'b0000; // dummy function
endcase
end
end
// modulated carrier
always @*
scarrier <= carrier[CARRIER_WIDTH:CARRIER_WIDTH-3] + phase;
// colour enable
assign cenable =
cg_enable == 1'b1 &&
cg_rgb != 3'b000 &&
cg_rgb != 3'b111;
// chroma signal
always @(posedge cg_clock) begin
cg_out[2] <= cenable;
cg_out[1] <= burst;
cg_out[0] <= scarrier[3];
end
endmodule

18
fpga/rtl/common.sv Executable file
View File

@ -0,0 +1,18 @@
package common;
typedef enum { TIMINGS_PENT,TIMINGS_S128,TIMINGS_S48 } timings_t;
typedef enum { TURBO_NONE, TURBO_7, TURBO_14} turbo_t;
endpackage
interface cpu_bus();
wire [15:0] a;
wire [7:0] d;
wire iorq;
wire mreq;
wire m1;
wire rfsh;
wire rd;
wire wr;
wire ioreq;
endinterface

115
fpga/rtl/cpucontrol.sv Executable file
View File

@ -0,0 +1,115 @@
import common::*;
module cpucontrol(
input rst_n,
input clk28,
input clk14,
input clk7,
input clk35,
cpu_bus bus,
output [7:0] d_out,
output d_out_active,
input [8:0] vc,
input [8:0] hc,
input [2:0] rampage128,
input screen_load,
input turbo_t turbo,
input timings_t timings,
input pause,
input ext_wait_cycle,
input init_done_in,
output n_rstcpu,
output clkcpu,
output clkcpu_ck,
output clkwait,
output n_int,
output n_int_next,
output snow
);
/* CONTENTION */
logic mreq_delayed, iorq_delayed;
always @(posedge clkcpu)
mreq_delayed <= bus.mreq;
always @(posedge clkcpu)
iorq_delayed <= bus.iorq;
wire contention_mem_addr = bus.a[14] & (~bus.a[15] | (bus.a[15] & rampage128[0]));
wire contention_mem = iorq_delayed == 1'b0 && mreq_delayed == 1'b0 && contention_mem_addr;
wire contention_io = iorq_delayed == 1'b0 && bus.iorq;
wire contention0 = screen_load && (hc[2] || hc[3]) && (contention_mem || contention_io);
wire contention = clkcpu && contention0 && turbo == TURBO_NONE && timings != TIMINGS_PENT;
assign snow = (timings != TIMINGS_PENT) && bus.a[14] && ~bus.a[15] && bus.rfsh;
/* CLOCK */
logic [2:0] turbo_wait;
wire turbo_wait_trig0 = bus.rd || bus.wr;
wire turbo_wait_trig1;
always @(posedge clk28) begin
turbo_wait_trig1 <= turbo_wait_trig0;
turbo_wait[0] <= turbo == TURBO_14 && turbo_wait_trig0 && !turbo_wait_trig1;
turbo_wait[1] <= turbo_wait[0] && (bus.iorq || ext_wait_cycle);
turbo_wait[2] <= turbo_wait[1];
end
logic clkcpu_prev;
assign clkcpu_ck = clkcpu && ! clkcpu_prev;
assign clkwait = pause || contention || (|turbo_wait);
always @(negedge clk28) begin
clkcpu_prev <= clkcpu;
clkcpu <= clkwait? clkcpu : (turbo == TURBO_14)? clk14 : (turbo == TURBO_7)? clk7 : clk35;
end
/* INT GENERATOR */
wire int_vector_rd = bus.iorq && bus.m1;
wire [7:0] int_vector_data = 8'hff;
localparam INT_V_S48 = 247;
localparam INT_H_S48 = 442;
localparam INT_V_S128 = 247;
localparam INT_H_S128 = 450;
localparam INT_V_PENT = 239;
localparam INT_H_PENT = 316;
wire int_begin =
(timings == TIMINGS_PENT)?
vc == INT_V_PENT && hc == INT_H_PENT :
(timings == TIMINGS_S128)?
vc == INT_V_S128 && hc == INT_H_S128 :
// 48K
vc == INT_V_S48 && hc == INT_H_S48 ;
logic [4:0] int_cnt;
assign n_int_next = (|int_cnt)? 1'b0 : 1'b1;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
int_cnt <= 0;
n_int <= 1'b1;
end
else begin
if (clkcpu_ck)
n_int <= n_int_next;
if ((int_cnt != 0 && clkcpu_ck) || (int_cnt == 0 && int_begin))
int_cnt <= int_cnt + 1'b1;
end
end
/* RESET */
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n)
n_rstcpu <= 0;
else if (!init_done_in)
n_rstcpu <= 0;
else if (vc[0])
n_rstcpu <= 1'b1;
end
/* BUS CONTROLLER */
assign d_out = int_vector_data;
assign d_out_active = int_vector_rd;
endmodule

135
fpga/rtl/divmmc.sv Executable file
View File

@ -0,0 +1,135 @@
module divmmc(
input rst_n,
input clk28,
input ck14,
input ck7,
input en,
cpu_bus bus,
output [7:0] d_out,
output d_out_active,
input sd_cd,
input sd_miso,
output sd_mosi,
output reg sd_sck,
output reg sd_cs,
input port_dffd_d4,
input port_1ffd_d0,
input magic_mode,
input magic_map,
output reg [3:0] div_page,
output div_map,
output div_ram,
output div_ramwr_mask,
output div_wait
);
reg div_automap, div_automap_next;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
div_automap_next <= 0;
div_automap <= 0;
end
else if (bus.m1 && bus.mreq && magic_map == 0) begin
if (sd_cd || !en || port_dffd_d4 || port_1ffd_d0) begin
div_automap_next <= 0;
end
else if (bus.a[15:3] == 13'h3FF) begin // exit vectors 1FF8-1FFF
div_automap_next <= 0;
end
else if (
bus.a == 16'h0000 || // power-on/reset/rst0/software restart
bus.a == 16'h0008 || // syntax error
bus.a == 16'h0038 || // im1 interrupt/rst #38
(bus.a == 16'h0066 && !magic_mode) || // nmi routine
bus.a == 16'h04C6 || // tape save routine
bus.a == 16'h0562 // tape load and verify routine
) begin
div_automap_next <= 1'b1;
end
else if (bus.a[15:8] == 8'h3D) begin // tr-dos mapping area
div_automap_next <= 1'b1;
div_automap <= 1'b1;
end
end
else if (!bus.m1) begin
div_automap <= div_automap_next;
end
end
reg spi_rd;
reg div_conmem, div_mapram;
wire port_e3_cs = en && bus.ioreq && bus.a[7:0] == 8'hE3;
wire port_e7_cs = en && bus.ioreq && bus.a[7:0] == 8'hE7;
wire port_eb_cs = en && bus.ioreq && bus.a[7:0] == 8'hEB;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
spi_rd <= 0;
div_page <= 0;
div_mapram <= 0;
div_conmem <= 0;
sd_cs <= 1'b1;
end
else begin
spi_rd <= port_eb_cs && bus.rd;
if (port_e3_cs && bus.wr) begin
div_page <= bus.d[3:0];
div_mapram <= bus.d[6] | div_mapram;
div_conmem <= bus.d[7];
end
if (port_e7_cs && bus.wr) begin
sd_cs <= bus.d[0];
end
end
end
reg [3:0] spi_cnt;
wire spi_cnt_en = ~spi_cnt[3] | spi_cnt[2] | spi_cnt[1] | spi_cnt[0];
assign div_wait = ~spi_cnt[3];
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n)
spi_cnt <= 0;
else if (port_eb_cs && (bus.rd || bus.wr))
spi_cnt <= 4'b1110;
else if (spi_cnt_en && ck7)
spi_cnt <= spi_cnt + 1'b1;
end
reg spi_mosi_en;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n)
spi_mosi_en <= 0;
else if (port_eb_cs && bus.wr)
spi_mosi_en <= 1'b1;
else if (!spi_cnt_en)
spi_mosi_en <= 0;
end
reg [7:0] spi_reg;
assign sd_mosi = spi_mosi_en? spi_reg[7] : 1'b1;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n)
spi_reg <= 0;
else if (port_eb_cs && bus.wr)
spi_reg <= bus.d;
else if (spi_cnt[3] == 1'b0 && ck7)
spi_reg[7:0] <= {spi_reg[6:0], sd_miso};
end
always @(posedge clk28) begin
if (ck14)
sd_sck <= ~sd_sck & ~spi_cnt[3];
end
assign div_map = div_automap | div_conmem;
assign div_ram = (div_conmem == 1 && bus.a[13] == 1) || (div_automap == 1 && bus.a[13] == 1) || (div_conmem == 0 && div_automap == 1 && div_mapram == 1);
assign div_ramwr_mask = bus.a[15] == 0 && bus.a[14] == 0 && (bus.a[13] == 0 || div_page == 4'b0011) && div_conmem == 0 && div_automap == 1 && div_mapram == 1;
assign d_out_active = spi_rd;
assign d_out = spi_reg;
endmodule

97
fpga/rtl/magic.sv Executable file
View File

@ -0,0 +1,97 @@
import common::*;
module magic(
input rst_n,
input clk28,
cpu_bus bus,
input n_int,
input n_int_next,
output n_nmi,
input magic_button,
output logic magic_mode,
output logic magic_map,
output magic_active_next,
output logic extlock,
output logic magic_beeper,
output timings_t timings,
output turbo_t turbo,
output logic joy_sinclair,
output logic rom_plus3,
output logic rom_alt48,
output logic ay_abc,
output logic ay_mono
);
assign magic_active_next = magic_button;
logic magic_unmap_next;
logic magic_map_next;
assign n_nmi = magic_mode? 1'b0 : 1'b1;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
magic_mode <= 0;
magic_map <= 0;
magic_unmap_next <= 0;
magic_map_next <= 0;
end
else begin
if (magic_button == 1'b1 && n_int == 1'b1 && n_int_next == 1'b0)
magic_mode <= 1'b1;
if (magic_map && bus.mreq && bus.rd && bus.a == 16'hf000 && !magic_map_next) begin
magic_unmap_next <= 1'b1;
magic_mode <= 1'b0;
end
else if (magic_map && bus.mreq && bus.rd && bus.a == 16'hf008) begin
magic_unmap_next <= 1'b1;
magic_map_next <= 1'b1;
end
else if (magic_unmap_next && !bus.mreq) begin
magic_map <= 1'b0;
magic_unmap_next <= 1'b0;
end
else if (magic_mode && bus.m1 && bus.mreq && (bus.a == 16'h0066 || magic_map_next)) begin
magic_map <= 1'b1;
magic_map_next <= 1'b0;
end
end
end
/* MAGIC CONFIG */
wire config_cs = magic_map && bus.ioreq && bus.a[7:0] == 8'hff;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
magic_beeper <= 0;
extlock <= 0;
timings <= TIMINGS_PENT;
turbo <= TURBO_NONE;
ay_abc <= 1'b1;
ay_mono <= 0;
rom_plus3 <= 0;
rom_alt48 <= 0;
joy_sinclair <= 0;
end
else if (config_cs && bus.wr) begin
if (bus.a[15:12] == 4'h0)
magic_beeper <= bus.d[0];
if (bus.a[15:12] == 4'h1)
extlock <= bus.d[0];
if (bus.a[15:12] == 4'h2)
timings <= timings_t'(bus.d[1:0]);
if (bus.a[15:12] == 4'h3)
turbo <= turbo_t'(bus.d[1:0]);
if (bus.a[15:12] == 4'h4)
{ay_mono, ay_abc} <= bus.d[1:0];
if (bus.a[15:12] == 4'h5)
rom_plus3 <= bus.d[0];
if (bus.a[15:12] == 4'h6)
rom_alt48 <= bus.d[0];
if (bus.a[15:12] == 4'h7)
joy_sinclair <= bus.d[0];
end
end
endmodule

55
fpga/rtl/mixer.sv Executable file
View File

@ -0,0 +1,55 @@
module mixer(
input rst_n,
input clk28,
input beeper,
input tape_out,
input tape_in,
input [7:0] ay_a0,
input [7:0] ay_b0,
input [7:0] ay_c0,
input [7:0] ay_a1,
input [7:0] ay_b1,
input [7:0] ay_c1,
input [7:0] sd_l0,
input [7:0] sd_l1,
input [7:0] sd_r0,
input [7:0] sd_r1,
input ay_abc,
input ay_mono,
output dac_l,
output dac_r
);
reg [10:0] dac_l_cnt, dac_r_cnt;
assign dac_l = dac_l_cnt[10];
assign dac_r = dac_r_cnt[10];
wire [9:0] dac_next_l =
sd_l0 + sd_l1 +
ay_a0 + ay_b0 +
ay_a1 + ay_b1 +
{beeper, tape_out, tape_in, 6'b000000}
;
wire [9:0] dac_next_r =
sd_r0 + sd_r1 +
ay_b0 + ay_c0 +
ay_b1 + ay_c1 +
{beeper, tape_out, tape_in, 6'b000000}
;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
dac_l_cnt <= 0;
dac_r_cnt <= 0;
end
else begin
dac_l_cnt <= dac_l_cnt[9:0] + dac_next_l;
dac_r_cnt <= dac_r_cnt[9:0] + dac_next_r;
end
end
endmodule

141
fpga/rtl/ports.sv Executable file
View File

@ -0,0 +1,141 @@
import common::*;
module ports(
input rst_n,
input clk28,
input en_128k,
input en_plus3,
input en_profi,
cpu_bus bus,
output [7:0] d_out,
output d_out_active,
input clkcpu_ck,
input timings_t timings,
input screen_load,
input [7:0] attr_next,
input [4:0] kd,
input [7:0] kempston_data,
input joy_sinclair,
input magic_active_next,
input sd_miso_tape_in,
output reg tape_out,
output reg beeper,
output reg [2:0] border,
output reg screen_page,
output reg rompage128,
output reg [2:0] rampage128,
output reg [3:0] rampage_ext,
output reg [2:0] port_1ffd,
output reg port_dffd_d3,
output reg port_dffd_d4
);
/* PORT #FF */
wire [7:0] port_ff_data = attr_next;
reg port_ff_rd;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n)
port_ff_rd <= 0;
else
port_ff_rd <= bus.rd && bus.ioreq && (timings != TIMINGS_PENT || bus.a[7:0] == 8'hFF) && screen_load;
end
/* PORT #FE */
wire port_fe_cs = bus.ioreq && bus.a[0] == 0;
reg port_fe_rd;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n)
port_fe_rd <= 0;
else
port_fe_rd <= port_fe_cs && bus.rd;
end
reg [4:0] kd0;
wire [7:0] port_fe_data = {~magic_active_next, sd_miso_tape_in, 1'b1, kd0};
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
beeper <= 0;
tape_out <= 0;
border <= 0;
end
else if (port_fe_cs && bus.wr && clkcpu_ck) begin // clkcpu_ck to synchronize border
beeper <= bus.d[4];
tape_out <= bus.d[3];
border <= bus.d[2:0];
end
end
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
kd0 <= 5'b11111;
end
else if (joy_sinclair) begin
kd0 <= kd
& (bus.a[12] == 0? {~kempston_data[1], ~kempston_data[0], ~kempston_data[2], ~kempston_data[3], ~kempston_data[4]} : 5'b11111) // 6-0 keys
& (bus.a[15] == 0? {1'b1, ~kempston_data[6], ~kempston_data[5], 2'b11} : 5'b11111 ) ; // b-space keys
end
else begin
kd0 <= kd;
end
end
/* PORT #7FFD */
wire port_7ffd_cs = en_128k && bus.ioreq && bus.a[1] == 0 && bus.a[15] == 0 && (bus.a[14] == 1'b1 || !en_plus3);
reg lock_7ffd;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
rampage128 <= 0;
screen_page <= 0;
rompage128 <= 0;
lock_7ffd <= 0;
end
else if (port_7ffd_cs && bus.wr && (lock_7ffd == 0 || port_dffd_d4 == 1'b1)) begin
rampage128 <= bus.d[2:0];
screen_page <= bus.d[3];
rompage128 <= bus.d[4];
lock_7ffd <= bus.d[5];
end
end
/* PORT #DFFD */
wire port_dffd_cs = en_profi && bus.ioreq && bus.a == 16'hDFFD;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
rampage_ext <= 0;
port_dffd_d3 <= 0;
port_dffd_d4 <= 0;
end
else if (port_dffd_cs && bus.wr) begin
rampage_ext <= bus.d[2:0];
port_dffd_d3 <= bus.d[3];
port_dffd_d4 <= bus.d[4];
end
end
/* PORT #1FFD */
wire port_1ffd_cs = en_plus3 && bus.ioreq && bus.a == 16'h1FFD;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
port_1ffd <= 0;
end
else if (port_1ffd_cs && bus.wr) begin
port_1ffd <= bus.d[2:0];
end
end
/* BUS CONTROLLER */
assign d_out_active = port_fe_rd | port_ff_rd;
assign d_out =
port_fe_rd? port_fe_data :
port_ff_data ;
endmodule

263
fpga/rtl/screen.sv Executable file
View File

@ -0,0 +1,263 @@
`include "util.vh"
import common::*;
module screen(
input rst_n,
input clk28,
cpu_bus bus,
output [14:0] screen_addr,
output [5:0] up_addr,
input clkwait,
input timings_t timings,
input [2:0] border,
input up_en,
output reg [1:0] r,
output reg [1:0] g,
output reg [1:0] b,
output reg vsync,
output reg hsync,
output reg csync,
output read,
output read_up,
output blink,
output load,
output reg [7:0] attr_next,
output [8:0] hc_out,
output [8:0] vc_out,
output clk14,
output clk7,
output clk35,
output ck14,
output ck7,
output ck35
);
localparam H_AREA = 256;
localparam V_AREA = 192;
localparam SCREEN_DELAY = 8;
localparam H_LBORDER_S48 = 48 - SCREEN_DELAY;
localparam H_RBORDER_S48 = 48 + SCREEN_DELAY;
localparam H_BLANK1_S48 = 17;
localparam H_SYNC_S48 = 33;
localparam H_BLANK2_S48 = 46;
localparam H_TOTAL_S48 = H_AREA + H_RBORDER_S48 + H_BLANK1_S48 + H_SYNC_S48 + H_BLANK2_S48 + H_LBORDER_S48;
localparam V_BBORDER_S48 = 56;
localparam V_SYNC_S48 = 8;
localparam V_TBORDER_S48 = 56;
localparam V_TOTAL_S48 = V_AREA + V_BBORDER_S48 + V_SYNC_S48 + V_TBORDER_S48;
localparam H_LBORDER_S128 = 48 - SCREEN_DELAY;
localparam H_RBORDER_S128 = 48 + SCREEN_DELAY;
localparam H_BLANK1_S128 = 25;
localparam H_SYNC_S128 = 33;
localparam H_BLANK2_S128 = 46;
localparam H_TOTAL_S128 = H_AREA + H_RBORDER_S128 + H_BLANK1_S128 + H_SYNC_S128 + H_BLANK2_S128 + H_LBORDER_S128;
localparam V_BBORDER_S128 = 55;
localparam V_SYNC_S128 = 8;
localparam V_TBORDER_S128 = 56;
localparam V_TOTAL_S128 = V_AREA + V_BBORDER_S128 + V_SYNC_S128 + V_TBORDER_S128;
localparam H_LBORDER_PENT = 54 - SCREEN_DELAY;
localparam H_RBORDER_PENT = 53 + SCREEN_DELAY;
localparam H_BLANK1_PENT = 12;
localparam H_SYNC_PENT = 33;
localparam H_BLANK2_PENT = 40;
localparam H_TOTAL_PENT = H_AREA + H_RBORDER_PENT + H_BLANK1_PENT + H_SYNC_PENT + H_BLANK2_PENT + H_LBORDER_PENT;
localparam V_BBORDER_PENT = 56;
localparam V_SYNC_PENT = 8;
localparam V_TBORDER_PENT = 64;
localparam V_TOTAL_PENT = V_AREA + V_BBORDER_PENT + V_SYNC_PENT + V_TBORDER_PENT;
reg [`CLOG2(`MAX(V_TOTAL_S128, V_TOTAL_PENT))-1:0] vc;
reg [`CLOG2(`MAX(H_TOTAL_S128, H_TOTAL_PENT))+1:0] hc0;
wire [`CLOG2(`MAX(H_TOTAL_S128, H_TOTAL_PENT))-1:0] hc = hc0[$bits(hc0)-1:2];
assign vc_out = vc;
assign hc_out = hc;
assign clk14 = hc0[0];
assign clk7 = hc0[1];
assign clk35 = hc0[2];
assign ck14 = hc0[0];
assign ck7 = hc0[0] & hc0[1];
assign ck35 = hc0[0] & hc0[1] & hc0[2];
wire hc0_reset =
(timings == TIMINGS_PENT)?
hc0 == (H_TOTAL_PENT<<2) - 1'b1 :
(timings == TIMINGS_S128)?
hc0 == (H_TOTAL_S128<<2) - 1'b1 :
// 48K
hc0 == (H_TOTAL_S48<<2) - 1'b1 ;
wire vc_reset =
(timings == TIMINGS_PENT)?
vc == V_TOTAL_PENT - 1'b1 :
(timings == TIMINGS_S128)?
vc == V_TOTAL_S128 - 1'b1 :
// 48K
vc == V_TOTAL_S48 - 1'b1;
wire hsync0 =
(timings == TIMINGS_PENT)?
(hc >= (H_AREA + H_RBORDER_PENT + H_BLANK1_PENT)) &&
(hc < (H_AREA + H_RBORDER_PENT + H_BLANK1_PENT + H_SYNC_PENT)) :
(timings == TIMINGS_S128)?
(hc >= (H_AREA + H_RBORDER_S128 + H_BLANK1_S128)) &&
(hc < (H_AREA + H_RBORDER_S128 + H_BLANK1_S128 + H_SYNC_S128)) :
// 48K
(hc >= (H_AREA + H_RBORDER_S48 + H_BLANK1_S48)) &&
(hc < (H_AREA + H_RBORDER_S48 + H_BLANK1_S48 + H_SYNC_S48)) ;
wire vsync0 =
(timings == TIMINGS_PENT)?
(vc >= (V_AREA + V_BBORDER_PENT)) && (vc < (V_AREA + V_BBORDER_PENT + V_SYNC_PENT)) :
(timings == TIMINGS_S128)?
(vc >= (V_AREA + V_BBORDER_S128)) && (vc < (V_AREA + V_BBORDER_S128 + V_SYNC_S128)) :
// 48K
(vc >= (V_AREA + V_BBORDER_S48)) && (vc < (V_AREA + V_BBORDER_S48 + V_SYNC_S48)) ;
wire blank =
(timings == TIMINGS_PENT)?
((vc >= (V_AREA + V_BBORDER_PENT)) && (vc < (V_AREA + V_BBORDER_PENT + V_SYNC_PENT))) ||
((hc >= (H_AREA + H_RBORDER_PENT)) &&
(hc < (H_AREA + H_RBORDER_PENT + H_BLANK1_PENT + H_SYNC_PENT + H_BLANK2_PENT))) :
(timings == TIMINGS_S128)?
((vc >= (V_AREA + V_BBORDER_S128)) && (vc < (V_AREA + V_BBORDER_S128 + V_SYNC_S128))) ||
((hc >= (H_AREA + H_RBORDER_S128)) &&
(hc < (H_AREA + H_RBORDER_S128 + H_BLANK1_S128 + H_SYNC_S128 + H_BLANK2_S128))) :
// 48K
((vc >= (V_AREA + V_BBORDER_S48)) && (vc < (V_AREA + V_BBORDER_S48 + V_SYNC_S48))) ||
((hc >= (H_AREA + H_RBORDER_S48)) &&
(hc < (H_AREA + H_RBORDER_S48 + H_BLANK1_S48 + H_SYNC_S48 + H_BLANK2_S48))) ;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
hc0 <= 0;
vc <= 0;
end
else if (hc0_reset) begin
hc0 <= 0;
if (vc_reset) begin
vc <= 0;
end
else begin
vc <= vc + 1'b1;
end
end
else begin
hc0 <= hc0 + 1'b1;
end
end
reg [4:0] blink_cnt;
assign blink = blink_cnt[$bits(blink_cnt)-1];
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n)
blink_cnt <= 0;
else if (hc0_reset && vc_reset)
blink_cnt <= blink_cnt + 1'b1;
end
wire [7:0] attr_border = {2'b00, border, 3'b000};
reg [7:0] bitmap, attr, bitmap_next;
reg [7:0] up_ink, up_paper, up_ink_next, up_paper_next;
wire pixel = bitmap[7];
reg screen_read;
assign read = screen_read;
reg [1:0] screen_read_step;
wire screen_read_step_reset = hc0[4:0] == 5'b11111 || hc0_reset;
wire bitmap_read = screen_read && screen_read_step == 2'd0;
wire attr_read = screen_read && screen_read_step == 2'd1;
wire up_ink_read = screen_read && screen_read_step == 2'd2;
wire up_paper_read = screen_read && screen_read_step == 2'd3;
assign read_up = up_ink_read || up_paper_read;
assign screen_addr = bitmap_read?
{ 2'b10, vc[7:6], vc[2:0], vc[5:3], hc[7:3] } :
{ 5'b10110, vc[7:3], hc[7:3] };
assign up_addr = up_ink_read?
{ attr_next[7:6], 1'b0, attr_next[2:0] } :
{ attr_next[7:6], 1'b1, attr_next[5:3] };
wire screen_load = (vc < V_AREA) && (hc < H_AREA || hc0_reset);
assign load = screen_load;
wire screen_show = (vc < V_AREA) && (hc0 >= (SCREEN_DELAY<<2) - 2) && (hc0 < ((H_AREA + SCREEN_DELAY)<<2) - 2);
wire screen_update = vc < V_AREA && hc <= H_AREA && hc != 0 && hc0[4:0] == 5'b11110;
wire border_update = !screen_show && ((timings == TIMINGS_PENT && ck7) || hc0[4:0] == 5'b11110);
wire bitmap_shift = hc0[1:0] == 2'b10;
wire screen_read_next = (screen_load || up_en) && ((!bus.iorq && !bus.mreq) || bus.rfsh || clkwait);
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
screen_read <= 0;
screen_read_step <= 0;
attr <= 0;
bitmap <= 0;
attr_next <= 0;
bitmap_next <= 0;
up_ink <= 0;
up_paper <= 0;
up_ink_next <= 0;
up_paper_next <= 0;
end
else begin
if (ck14) begin
screen_read <= screen_read_next;
if (screen_read && screen_read_step[0] && !up_en)
screen_read_step <= 0;
else if (!screen_load && up_en)
screen_read_step <= 2'd3;
else if (screen_read_step_reset)
screen_read_step <= 0;
else if (screen_read)
screen_read_step <= screen_read_step + 1'b1;
if (attr_read)
attr_next <= bus.d;
else if (!screen_load)
attr_next <= attr_border;
if (bitmap_read)
bitmap_next <= bus.d;
if (up_ink_read)
up_ink_next <= bus.d;
if (up_paper_read)
up_paper_next <= bus.d;
end
if (border_update)
attr <= attr_border;
else if (screen_update)
attr <= attr_next;
if (screen_update)
bitmap <= bitmap_next;
else if (bitmap_shift)
bitmap <= {bitmap[6:0], 1'b0};
if (screen_update)
up_ink <= up_ink_next;
if (screen_update || (!screen_show && !screen_load))
up_paper <= up_paper_next;
end
end
always @(posedge clk28) begin
if (blank)
{g, r, b} = 6'b000000;
else if (up_en) begin
g = pixel? up_ink[7:5] : up_paper[7:5];
r = pixel? up_ink[4:2] : up_paper[4:2];
b = pixel? up_ink[1:0] : up_paper[1:0];
end
else begin
{g[1], r[1], b[1]} = (pixel ^ (attr[7] & blink))? attr[2:0] : attr[5:3];
{g[0], r[0], b[0]} = ((g[1] | r[1] | b[1]) & attr[6])? 3'b111 : 3'b000;
end
csync = ~(vsync0 ^ hsync0);
vsync = ~vsync0;
hsync = ~hsync0;
end
endmodule

41
fpga/rtl/soundrive.sv Executable file
View File

@ -0,0 +1,41 @@
module soundrive(
input rst_n,
input clk28,
input en_soundrive,
input en_covox,
cpu_bus bus,
output reg [7:0] ch_l0,
output reg [7:0] ch_l1,
output reg [7:0] ch_r0,
output reg [7:0] ch_r1
);
wire covox_cs = en_covox && bus.ioreq && bus.a[7:0] == 8'hFB;
wire soundrive_a_cs = en_soundrive && bus.ioreq == 0 && bus.a[7:0] == 8'h0F;
wire soundrive_b_cs = en_soundrive && bus.ioreq == 0 && bus.a[7:0] == 8'h1F;
wire soundrive_c_cs = en_soundrive && bus.ioreq == 0 && bus.a[7:0] == 8'h4F;
wire soundrive_d_cs = en_soundrive && bus.ioreq == 0 && bus.a[7:0] == 8'h5F;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
ch_l0 <= 8'h80;
ch_l1 <= 8'h80;
ch_r0 <= 8'h80;
ch_r1 <= 8'h80;
end
else begin
if ((covox_cs || soundrive_a_cs) && bus.wr)
ch_l0 <= bus.d;
if ((covox_cs || soundrive_b_cs) && bus.wr)
ch_l1 <= bus.d;
if ((covox_cs || soundrive_c_cs) && bus.wr)
ch_r0 <= bus.d;
if ((covox_cs || soundrive_d_cs) && bus.wr)
ch_r1 <= bus.d;
end
end
endmodule

548
fpga/rtl/top.sv Executable file
View File

@ -0,0 +1,548 @@
import common::*;
module zx_ula(
input clk_in,
output reg n_rstcpu,
output reg clkcpu,
inout [18:0] va,
inout [7:0] vd,
input [15:13] a,
output n_vrd,
output n_vwr,
input n_rd,
input n_wr,
input n_mreq,
input n_iorq,
input n_m1,
input n_rfsh,
output reg n_int,
output n_nmi,
output reg [5:0] vdac,
output reg [2:0] chroma,
output reg csync,
output snd_l,
output snd_r,
inout reg ps2_clk,
inout reg ps2_data,
input sd_cd,
input sd_miso_tape_in,
output sd_mosi,
output reg sd_sck,
output reg sd_cs
);
/* CLOCK */
wire clk28 = clk_in;
wire clk40;
wire clk20;
wire rst_n;
pll pll0(.inclk0(clk_in), .c0(clk40), .c1(clk20), .locked(rst_n));
/* REGISTER DEFINITIONS */
timings_t timings;
turbo_t turbo;
wire clkwait;
reg magic_beeper;
wire pause = 0;
reg n_iorq_delayed;
always @(posedge clk28)
n_iorq_delayed <= n_iorq;
cpu_bus bus();
always @* begin
bus.a = {a[15:13], va[12:0]};
bus.d = vd;
bus.iorq = ~n_iorq;
bus.mreq = ~n_mreq;
bus.m1 = ~n_m1;
bus.rfsh = ~n_rfsh;
bus.rd = ~n_rd;
bus.wr = ~n_wr;
bus.ioreq = n_m1 == 1'b1 && n_iorq == 1'b0 && n_iorq_delayed == 1'b0;
end
/* SCREEN CONTROLLER */
reg [2:0] border;
reg up_en;
reg [1:0] r, g, b;
reg hsync;
wire blink;
wire [2:0] screen_border = {border[2] ^ ~sd_cd, border[1] ^ magic_beeper, border[0] ^ (pause & blink)};
wire screen_read, screen_load, screen_read_up;
wire [14:0] screen_addr;
wire [5:0] screen_up_addr;
wire [7:0] attr_next;
wire [8:0] vc, hc;
wire clk14, clk7, clk35, ck14, ck7, ck35;
screen screen0(
.rst_n(rst_n),
.clk28(clk28),
.bus(bus),
.screen_addr(screen_addr),
.up_addr(screen_up_addr),
.clkwait(clkwait),
.timings(timings),
.border(screen_border),
.up_en(up_en),
.r(r),
.g(g),
.b(b),
.csync(csync),
.hsync(hsync),
.blink(blink),
.read(screen_read),
.read_up(screen_read_up),
.load(screen_load),
.attr_next(attr_next),
.vc_out(vc),
.hc_out(hc),
.clk14(clk14),
.clk7(clk7),
.clk35(clk35),
.ck14(ck14),
.ck7(ck7),
.ck35(ck35)
);
always @*
vdac <= {r, g, b};
reg [2:0] chroma0;
chroma_gen #(.CLK_FREQ(40_000_000)) chroma_gen1(
.cg_clock(clk40),
.cg_rgb({g[1],r[1],b[1]}),
.cg_hsync(hsync),
.cg_enable(1'b1),
.cg_pnsel(1'b0),
.cg_out(chroma0)
);
assign chroma[0] = chroma0[1]? chroma0[0] : 1'bz;
assign chroma[1] = chroma0[2]? chroma0[0] : 1'bz;
assign chroma[2] = 1'bz;
/* CPU CONTROLLER */
wire div_wait;
wire [7:0] cpucontrol_dout;
wire cpucontrol_dout_active;
logic n_int_next;
wire snow, clkcpu_ck;
wire init_done;
cpucontrol cpucontrol0(
.rst_n(rst_n),
.clk28(clk28),
.clk14(clk14),
.clk7(clk7),
.clk35(clk35),
.bus(bus),
.d_out(cpucontrol_dout),
.d_out_active(cpucontrol_dout_active),
.vc(vc),
.hc(hc),
.rampage128(rampage128),
.screen_load(screen_load),
.turbo(turbo),
.timings(timings),
.pause(pause),
.ext_wait_cycle(div_wait || up_en),
.init_done_in(init_done),
.n_rstcpu(n_rstcpu),
.clkcpu(clkcpu),
.clkcpu_ck(clkcpu_ck),
.clkwait(clkwait),
.n_int(n_int),
.n_int_next(n_int_next),
.snow(snow)
);
/* MAGIC */
reg magic_mode, magic_map;
wire magic_active_next;
reg n_nmi0;
reg extlock, joy_sinclair, rom_plus3, rom_alt48, ay_abc, ay_mono;
magic magic0(
.rst_n(rst_n),
.clk28(clk28),
.bus(bus),
.n_int(n_int),
.n_int_next(n_int_next),
.n_nmi(n_nmi),
.magic_button(0),
.magic_mode(magic_mode),
.magic_map(magic_map),
.magic_active_next(magic_active_next),
.extlock(extlock),
.magic_beeper(magic_beeper),
.timings(timings),
.turbo(turbo),
.joy_sinclair(joy_sinclair),
.rom_plus3(rom_plus3),
.rom_alt48(rom_alt48),
.ay_abc(ay_abc),
.ay_mono(ay_mono)
);
/* PORTS */
wire [7:0] ports_dout;
wire ports_dout_active;
reg beeper, tape_out;
reg screenpage;
reg rompage128;
reg [2:0] rampage128;
reg [2:0] rampage_ext;
reg [2:0] port_1ffd;
reg port_dffd_d3;
reg port_dffd_d4;
ports ports0 (
.rst_n(rst_n),
.clk28(clk28),
.bus(bus),
.d_out(ports_dout),
.d_out_active(ports_dout_active),
.en_128k(1),
.en_plus3(!extlock),
.en_profi(!extlock),
.clkcpu_ck(clkcpu_ck),
.timings(timings),
.screen_load(screen_load),
.attr_next(attr_next),
.kd(5'b11111),
.kempston_data(8'b11111111),
.joy_sinclair(joy_sinclair),
.magic_active_next(magic_active_next),
.sd_miso_tape_in(sd_miso_tape_in),
.tape_out(tape_out),
.beeper(beeper),
.border(border),
.screen_page(screenpage),
.rompage128(rompage128),
.rampage128(rampage128),
.rampage_ext(rampage_ext),
.port_1ffd(port_1ffd),
.port_dffd_d3(port_dffd_d3),
.port_dffd_d4(port_dffd_d4)
);
/* AY */
reg ay_clk;
reg ay_bdir;
reg ay_bc1;
reg ay_sel;
wire ay_rd0 = ay_bc1 & ~ay_bdir & ~ay_sel;
wire ay_rd1 = ay_bc1 & ~ay_bdir & ay_sel;
wire port_bffd = bus.ioreq && bus.a[15] == 1'b1 && bus.a[7:0] == 8'hFD;
wire port_fffd = bus.ioreq && bus.a[15] == 1'b1 && bus.a[14] == 1'b1 && bus.a[7:0] == 8'hFD;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
ay_clk <= 0;
ay_bc1 <= 0;
ay_bdir <= 0;
end
else begin
if (ck35)
ay_clk = pause | ~ay_clk;
ay_bc1 <= ay_sel && port_fffd;
ay_bdir <= ay_sel && port_bffd && bus.wr;
if (bus.ioreq && port_fffd && bus.wr && bus.d[7:3] == 5'b11111)
ay_sel <= ~bus.d[0];
end
end
wire [7:0] ay_dout0, ay_dout1;
wire [7:0] ay_a0, ay_b0, ay_c0, ay_a1, ay_b1, ay_c1;
YM2149 ym2149_0(
.CLK(clk28),
.ENA(1'b0),
.RESET_H(~rst_n),
.I_SEL_L(1'b1),
.I_DA(bus.d),
.O_DA(ay_dout0),
.busctrl_addr(ay_bc1),
.busctrl_we(ay_bdir & ~ay_sel),
.ctrl_aymode(1'b1),
.port_a_i(8'hff),
.port_b_i(8'hff),
.O_AUDIO_A(ay_a0),
.O_AUDIO_B(ay_b0),
.O_AUDIO_C(ay_c0)
);
YM2149 ym2149_1(
.CLK(clk28),
.ENA(1'b0),
.RESET_H(~rst_n),
.I_SEL_L(1'b1),
.I_DA(bus.d),
.O_DA(ay_dout1),
.busctrl_addr(ay_bc1),
.busctrl_we(ay_bdir & ay_sel),
.ctrl_aymode(1'b1),
.port_a_i(8'hff),
.port_b_i(8'hff),
.O_AUDIO_A(ay_a1),
.O_AUDIO_B(ay_b1),
.O_AUDIO_C(ay_c1)
);
/* COVOX & SOUNDRIVE */
reg [7:0] soundrive_l0, soundrive_l1, soundrive_r0, soundrive_r1;
soundrive soundrive0(
.rst_n(rst_n),
.clk28(clk28),
.en_covox(!extlock),
.en_soundrive(!extlock),
.bus(bus),
.ch_l0(soundrive_l0),
.ch_l1(soundrive_l1),
.ch_r0(soundrive_r0),
.ch_r1(soundrive_r1)
);
/* SOUND MIXER */
mixer mixer0(
.rst_n(rst_n),
.clk28(clk28),
.beeper(beeper),
.tape_out(tape_out),
.tape_in(sd_miso_tape_in),
.ay_a0(ay_a0),
.ay_b0(ay_b0),
.ay_c0(ay_c0),
.ay_a1(ay_a1),
.ay_b1(ay_b1),
.ay_c1(ay_c1),
.sd_l0(soundrive_l0),
.sd_l1(soundrive_l1),
.sd_r0(soundrive_r0),
.sd_r1(soundrive_r1),
.dac_l(snd_l),
.dac_r(snd_r)
);
/* DIVMMC */
wire div_map, div_ram, div_ramwr_mask, div_dout_active;
wire [7:0] div_dout;
reg [3:0] div_page;
reg sd_mosi0;
divmmc divmmc0(
.rst_n(rst_n),
.clk28(clk28),
.ck14(ck14),
.ck7(ck7),
.en(!extlock),
.bus(bus),
.d_out(div_dout),
.d_out_active(div_dout_active),
.sd_cd(sd_cd | 1),
.sd_miso(sd_miso_tape_in),
.sd_mosi(sd_mosi0),
.sd_sck(sd_sck),
.sd_cs(sd_cs),
.port_dffd_d4(port_dffd_d4),
.port_1ffd_d0(port_1ffd[0]),
.magic_mode(magic_mode),
.magic_map(magic_map),
.div_page(div_page),
.div_map(div_map),
.div_ram(div_ram),
.div_ramwr_mask(div_ramwr_mask),
.div_wait(div_wait)
);
assign sd_mosi = (sd_cs == 1'b0)? sd_mosi0 : tape_out;
/* ULAPLUS */
wire port_bf3b_cs = !extlock && bus.ioreq && bus.a == 16'hbf3b;
wire port_ff3b_cs = !extlock && bus.ioreq && bus.a == 16'hff3b;
reg port_ff3b_rd;
wire [7:0] port_ff3b_data = {7'b0000000, up_en};
reg [7:0] up_addr_reg;
reg up_write_req;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
port_ff3b_rd <= 1'b0;
up_en <= 1'b0;
up_write_req <= 1'b0;
up_addr_reg <= 1'b0;
end
else begin
port_ff3b_rd <= port_ff3b_cs && n_rd == 1'b0;
if (n_wr == 1'b0) begin
if (port_bf3b_cs)
up_addr_reg <= bus.d;
if (port_ff3b_cs) begin
if (up_addr_reg == 8'b01000000)
up_en <= bus.d[0];
else if (up_addr_reg[7:6] == 2'b00)
up_write_req <= 1'b1;
end
end
else begin
up_write_req <= 0;
end
end
end
/* MEMORY INITIALIZER */
wire rom2ram_clk = clk35;
wire [14:0] rom2ram_ram_address, rom2ram_rom_address;
wire [7:0] rom2ram_datain, rom2ram_dataout;
wire rom2ram_rom_rden;
wire rom2ram_rom_data_ready;
wire rom2ram_ram_wren;
wire rom2ram_active;
assign init_done = !rom2ram_active;
reg [1:0] rom2ram_init;
always @(posedge rom2ram_clk or negedge rst_n) begin
if (!rst_n)
rom2ram_init <= 0;
else if (rom2ram_init != 3)
rom2ram_init <= rom2ram_init + 1'b1;
end
rom2ram rom2ram0(
.clock(rom2ram_clk),
.init(rom2ram_init == 2),
.datain(rom2ram_datain),
.rom_data_ready(rom2ram_rom_data_ready),
.init_busy(rom2ram_active),
.rom_address(rom2ram_rom_address),
.rom_rden(rom2ram_rom_rden),
.ram_wren(rom2ram_ram_wren),
.ram_address(rom2ram_ram_address),
.dataout(rom2ram_dataout)
);
localparam ROM_OFFSET = 24'h00013256;
wire [23:0] asmi_addr = ROM_OFFSET + rom2ram_rom_address;
asmi asmi0(
.clkin(rom2ram_clk),
.read(rom2ram_rom_rden),
.rden(rom2ram_active),
.addr(asmi_addr),
.reset(!rst_n),
.dataout(rom2ram_datain),
.busy(),
.data_valid(rom2ram_rom_data_ready)
);
/* MEMORY CONTROLLER */
reg romreq, ramreq, ramreq_wr;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
romreq = 1'b0;
ramreq = 1'b0;
ramreq_wr = 1'b0;
end
else begin
romreq = bus.mreq && !bus.rfsh && bus.a[14] == 0 && bus.a[15] == 0 &&
(magic_map || (!div_ram && div_map) || (!div_ram && !port_dffd_d4 && !port_1ffd[0]));
ramreq = (bus.mreq && !bus.rfsh && !romreq) || up_write_req;
ramreq_wr = ramreq && bus.wr && div_ramwr_mask == 0;
end
end
assign n_vrd = ((((ramreq || romreq) && bus.rd) || screen_read) && !rom2ram_ram_wren)? 1'b0 : 1'b1;
assign n_vwr = ((ramreq_wr && bus.wr && !screen_read) || rom2ram_ram_wren)? 1'b0 : 1'b1;
/* VA[18:13] map
* 00xxxx 128Kb of roms
* 00111x 16Kb of magic ram and ulaplus
* 01xxxx 128Kb of divmmc memory
* 10xxxx 128Kb of extended ram (via port dffd)
* 11xxxx 128Kb of main ram
*/
reg [18:13] ram_a;
always @(posedge clk28) begin
ram_a <=
magic_map & bus.a[15] & bus.a[14]? {2'b00, 3'b111, bus.a[13]} :
magic_map? {3'b111, screenpage, bus.a[14:13]} :
div_map & ~bus.a[14] & ~bus.a[15] & bus.a[13]? {2'b01, div_page} :
div_map & ~bus.a[14] & ~bus.a[15]? {2'b01, 4'b0011} :
port_dffd_d3 & bus.a[15]? {2'b11, bus.a[14], bus.a[15], bus.a[14], bus.a[13]} :
port_dffd_d3 & bus.a[14]? {1'b1, ~rampage_ext[0], rampage128, bus.a[13]} :
(port_1ffd[2] == 1'b0 && port_1ffd[0] == 1'b1)? {2'b11, port_1ffd[1], bus.a[15], bus.a[14], bus.a[13]} :
(port_1ffd == 3'b101)? {2'b11, ~(bus.a[15] & bus.a[14]), bus.a[15], bus.a[14]} :
(port_1ffd == 3'b111)? {2'b11, ~(bus.a[15] & bus.a[14]), (bus.a[15] | bus.a[14]), bus.a[14]} :
bus.a[15] & bus.a[14]? {1'b1, ~rampage_ext[0], rampage128, bus.a[13]} :
{2'b11, bus.a[14], bus.a[15], bus.a[14], bus.a[13]} ;
end
reg [16:14] rom_a;
always @(posedge clk28) begin
rom_a <=
magic_map? 3'd2 :
div_map? 3'd3 :
(rom_plus3 && port_1ffd[2] == 1'b0 && rompage128 == 1'b0)? 3'd4 :
(rom_plus3 && port_1ffd[2] == 1'b0 && rompage128 == 1'b1)? 3'd5 :
(rom_plus3 && port_1ffd[2] == 1'b1 && rompage128 == 1'b0)? 3'd6 :
(rompage128 == 1'b1 && rom_alt48 == 1'b1)? 3'd7 :
(rompage128 == 1'b1)? 3'd1 :
3'd0;
end
assign va[18:0] =
rom2ram_ram_wren? {4'b0000, rom2ram_ram_address} :
screen_read && screen_read_up? {2'b00, 3'b111, 8'b11111111, screen_up_addr} :
screen_read && snow? {3'b111, screenpage, screen_addr[14:8], bus.a[7:0]} :
screen_read? {3'b111, screenpage, screen_addr} :
up_write_req? {2'b00, 3'b111, 8'b11111111, up_addr_reg[5:0]} :
romreq? {2'b00, rom_a[16:14], bus.a[13], {13{1'bz}}} :
{ram_a[18:13], {13{1'bz}}};
assign vd[7:0] =
rom2ram_ram_wren? rom2ram_dataout :
port_ff3b_rd? port_ff3b_data :
ay_rd0? ay_dout0 :
ay_rd1? ay_dout1 :
div_dout_active? div_dout :
ports_dout_active? ports_dout :
cpucontrol_dout_active? cpucontrol_dout :
{8{1'bz}};
endmodule

383
fpga/rtl/usbhost/ls_usb_core.v Executable file
View File

@ -0,0 +1,383 @@
//simplest low speed USB CORE function
module ls_usb_core(
//clock should be 5Mhz
input wire clk,
input wire EOP,
input wire [7:0]data,
input wire wre,
input wire [3:0]rbyte_cnt,
input wire show_next,
output reg [7:0]sbyte,
output reg start_pkt,
output reg last_pkt_byte,
output reg [7:0]leds
);
//PIDs of last 2 received packets
reg [3:0]pid0;
reg [3:0]pid1;
reg [1:0]toggle;
always @(posedge clk)
begin
if( (rbyte_cnt==4'h1) & wre)
begin
pid1 <= pid0;
pid0 <= data[3:0];
end
end
reg [3:0]setup_req;
always @(posedge clk)
begin
if( (rbyte_cnt==4'h3) & wre & (pid1==4'hd) )
setup_req <= data[3:0];
end
always @(posedge clk)
begin
if( (rbyte_cnt==4'h6) & wre & (pid1==4'hd) )
leds <= data[7:0];
end
/*
reg setup_val0;
always @(posedge clk)
begin
if( (rbyte_cnt==4'h4) & wre & (pid1==4'hd) )
setup_val0 <= data[0];
end
*/
reg [3:0]setup_val;
always @(posedge clk)
begin
if( (rbyte_cnt==4'h5) & wre & (pid1==4'hd) )
setup_val <= data[3:0];
end
reg [3:0]setup_len;
always @(posedge clk)
begin
if( (rbyte_cnt==4'h8) & wre & (pid1==4'hd) )
setup_len <= data[3:0];
end
//sending bytes table
reg [7:0]sptr;
reg [7:0]sb; //byte for send and flag for last packet
always @*
begin
case(sptr)
//ACK packet
8'h00: sb = 8'h81; //SYN
8'h01: sb = 8'hD2; //last in packet
8'h02: sb = 8'h00;
8'h03: sb = 8'h00;
8'h04: sb = 8'h00;
8'h05: sb = 8'h00;
8'h06: sb = 8'h00;
8'h07: sb = 8'h00;
8'h08: sb = 8'h00;
8'h09: sb = 8'h00;
8'h0a: sb = 8'h00;
8'h0b: sb = 8'h00;
8'h0c: sb = 8'h00;
8'h0d: sb = 8'h00;
8'h0e: sb = 8'h00;
8'h0f: sb = 8'h00;
//config descriptor
8'h10: sb = 8'h8b; //SYN
8'h11: sb = 8'h4B;
8'h12: sb = 8'h12; //12 01 00 01 FF 00 00 08 23 f3
8'h13: sb = 8'h01;
8'h14: sb = 8'h00;
8'h15: sb = 8'h01;
8'h16: sb = 8'hff;
8'h17: sb = 8'h00;
8'h18: sb = 8'h00;
8'h19: sb = 8'h08;
8'h1a: sb = 8'h23;
8'h1b: sb = 8'hf3; //last in packet
8'h1c: sb = 8'h00;
8'h1d: sb = 8'h00;
8'h1e: sb = 8'h00;
8'h1f: sb = 8'h00;
//config descriptor continued
8'h20: sb = 8'h8b; //SYN
8'h21: sb = 8'hC3;
8'h22: sb = 8'hB9; //B9 04 00 03 00 02 02 01 14 4a
8'h23: sb = 8'h04;
8'h24: sb = 8'h00;
8'h25: sb = 8'h03;
8'h26: sb = 8'h00;
8'h27: sb = 8'h02;
8'h28: sb = 8'h02;
8'h29: sb = 8'h00;
8'h2a: sb = 8'hd5;
8'h2b: sb = 8'h8a;
8'h2c: sb = 8'h00;
8'h2d: sb = 8'h00;
8'h2e: sb = 8'h00;
8'h2f: sb = 8'h00;
//config descriptor continued
8'h30: sb = 8'h85; //SYN
8'h31: sb = 8'h4B;
8'h32: sb = 8'h00; //00 01 3f 8f
8'h33: sb = 8'h01;
8'h34: sb = 8'h3f;
8'h35: sb = 8'h8f;
8'h36: sb = 8'h00;
8'h37: sb = 8'h00;
8'h38: sb = 8'h00;
8'h39: sb = 8'h00;
8'h3a: sb = 8'h00;
8'h3b: sb = 8'h00;
8'h3c: sb = 8'h00;
8'h3d: sb = 8'h00;
8'h3e: sb = 8'h00;
8'h3f: sb = 8'h00;
//empty IN
8'h40: sb = 8'h83; //SYN
8'h41: sb = 8'h4B;
8'h42: sb = 8'h00;
8'h43: sb = 8'h00;
8'h44: sb = 8'h00;
8'h45: sb = 8'h00;
8'h46: sb = 8'h00;
8'h47: sb = 8'h00;
8'h48: sb = 8'h00;
8'h49: sb = 8'h00;
8'h4a: sb = 8'h00;
8'h4b: sb = 8'h00;
8'h4c: sb = 8'h00;
8'h4d: sb = 8'h00;
8'h4e: sb = 8'h00;
8'h4f: sb = 8'h00;
//config descriptor configuration
8'h50: sb = 8'h8b; //SYN
8'h51: sb = 8'h4B;
8'h52: sb = 8'h09;
8'h53: sb = 8'h02;
8'h54: sb = 8'h14;
8'h55: sb = 8'h00;
8'h56: sb = 8'h01;
8'h57: sb = 8'h01;
8'h58: sb = 8'h00;
8'h59: sb = 8'h80;
8'h5a: sb = 8'h0e;
8'h5b: sb = 8'hd6;
8'h5c: sb = 8'h00;
8'h5d: sb = 8'h00;
8'h5e: sb = 8'h00;
8'h5f: sb = 8'h00;
//config descriptor configuration continued
8'h60: sb = 8'h84; //SYN
8'h61: sb = 8'hC3;
8'h62: sb = 8'h0d;
8'h63: sb = 8'h81;
8'h64: sb = 8'h7a;
8'h65: sb = 8'h00;
8'h66: sb = 8'h00;
8'h67: sb = 8'h00;
8'h68: sb = 8'h00;
8'h69: sb = 8'h00;
8'h6a: sb = 8'h00;
8'h6b: sb = 8'h00;
8'h6c: sb = 8'h00;
8'h6d: sb = 8'h00;
8'h6e: sb = 8'h00;
8'h6f: sb = 8'h00;
//config descriptor configuration
8'h70: sb = 8'h8b; //SYN
8'h71: sb = 8'h4B;
8'h72: sb = 8'h09;
8'h73: sb = 8'h02;
8'h74: sb = 8'h14;
8'h75: sb = 8'h00;
8'h76: sb = 8'h01;
8'h77: sb = 8'h01;
8'h78: sb = 8'h00;
8'h79: sb = 8'h80;
8'h7a: sb = 8'h0e;
8'h7b: sb = 8'hd6;
8'h7c: sb = 8'h00;
8'h7d: sb = 8'h00;
8'h7e: sb = 8'h00;
8'h7f: sb = 8'h00;
//config descriptor configuration continued
8'h80: sb = 8'h8b; //SYN
8'h81: sb = 8'hC3;
8'h82: sb = 8'h0d;
8'h83: sb = 8'h09;
8'h84: sb = 8'h04;
8'h85: sb = 8'h00;
8'h86: sb = 8'h00;
8'h87: sb = 8'h00;
8'h88: sb = 8'hff;
8'h89: sb = 8'h00;
8'h8a: sb = 8'ha7;
8'h8b: sb = 8'h19;
8'h8c: sb = 8'h00;
8'h8d: sb = 8'h00;
8'h8e: sb = 8'h00;
8'h8f: sb = 8'h00;
//config descriptor configuration continued
8'h90: sb = 8'h87; //SYN
8'h91: sb = 8'h4B;
8'h92: sb = 8'h00;
8'h93: sb = 8'h00;
8'h94: sb = 8'h02;
8'h95: sb = 8'h40;
8'h96: sb = 8'hff;
8'h97: sb = 8'h4b;
8'h98: sb = 8'h00;
8'h99: sb = 8'h00;
8'h9a: sb = 8'h00;
8'h9b: sb = 8'h00;
8'h9c: sb = 8'h00;
8'h9d: sb = 8'h00;
8'h9e: sb = 8'h00;
8'h9f: sb = 8'h00;
default:
sb = 8'h00;
endcase
end
reg [1:0]state;
reg [3:0]pkt_len;
always @(posedge clk)
begin
if(sptr[3:0]==4'h0)
pkt_len <= sb[3:0];
/*
if(sptr[3:0]==4'h0)
sbyte <= {sb[7:4],4'b0000};
else
sbyte <= sb;
last_pkt_byte <= (sptr[3:0]==pkt_len);
*/
end
always @*
begin
if(sptr[3:0]==4'h0)
sbyte = {sb[7:4],4'b0000};
else
sbyte = sb;
last_pkt_byte = (sptr[3:0]==pkt_len);
end
always @(posedge clk)
begin
if( (state==0) & (!EOP) )
begin
if(pid0==4'hd) //0x2D
toggle <= 2'b00;
else
if(pid0==4'h9) //0x69
toggle <= toggle + 1'b1;
end
end
always @(posedge clk or posedge EOP)
begin
if(EOP)
begin
//kind of reset
start_pkt <= 1'b0;
state <= 0;
sptr <= 8'h00;
end
else
begin
start_pkt <= (state==2'b10);
case(state)
0:
begin
//do nothing but just after EOP check last PIDs
if( ((pid0==4'hb) | (pid0==4'h3)) & ((pid1==4'hd) | (pid1==4'h1)) ) // (0x4b or 0xc3) and (0x2d and 0xE1)
begin
state <= 2; //should send packet
sptr[7:4] <= 4'h0; //packet will be ACK
sptr[3:0] <= 4'h0;
end
else
if( (pid0==4'h9)&(setup_req==4'h6)&(setup_val==4'h1))
begin
state <= 2; //should send packet
sptr[7:4] <= 4'h1+toggle; //packet will be config descriptor
sptr[3:0] <= 4'h0;
end
else
if( (pid0==4'h9)&(setup_req==4'h6)&(setup_val==4'h2)&(setup_len==4'h9))
begin
state <= 2; //should send packet
sptr[7:4] <= 4'h5+toggle; //packet will be config descriptor configuration
sptr[3:0] <= 4'h0;
end
else
if( (pid0==4'h9)&(setup_req==4'h6)&(setup_val==4'h2)&(setup_len!=4'h9))
begin
state <= 2; //should send packet
sptr[7:4] <= 4'h7+toggle; //packet will be config descriptor configuration
sptr[3:0] <= 4'h0;
end
else
if(pid0==4'h9)
begin
state <= 2; //should send packet
sptr[7:4] <= 4'h4; //empty IN
sptr[3:0] <= 4'h0;
end
else
begin
state <= 1; //should do nothing
sptr<=8'h00;
end
end
1:
begin
//do nothing
state <= 1;
sptr <= 8'h00;
end
2:
begin
//initiate send packet
state <= 3;
sptr <= sptr;
end
3:
begin
state <= 3;
sptr[3:0] <= sptr[3:0] + show_next;
sptr[7:4] <= sptr[7:4];
end
endcase
end
end
endmodule

172
fpga/rtl/usbhost/ls_usb_recv.v Executable file
View File

@ -0,0 +1,172 @@
//simplest low speed USB receive function
module ls_usb_recv(
input wire reset,
//clock should be 12Mhz
input wire clk,
//usb BUS signals
input wire dp,
input wire dm,
input wire enable,
output wire eop_r,
//output received bytes interface
output reg [7:0]rdata,
output reg rdata_ready,
output reg [3:0]rbyte_cnt,
output wire eop_rfe //receive EOP falling edge
);
////////////////////////////////////////////////////////
//receiver regs
////////////////////////////////////////////////////////
reg [2:0]receiver_cnt;
//fix current USB line values
reg [1:0]dp_input;
reg [1:0]dm_input;
always @(posedge clk)
begin
dp_input <= { dp_input[0], dp };
dm_input <= { dm_input[0], dm };
end
//if both lines in ZERO this is low speed EOP
//EOP reinitializes receiver
assign eop_r = !(dp_input[0] | dp_input[1] | dm_input[0] | dm_input[1]);
//find edge of receive EOP
assign eop_rfe = receiver_enabled & (eop_r);
//logic for enabling/disabling receiver
reg receiver_enabled;
always @(posedge clk or posedge reset )
if(reset)
receiver_enabled <= 1'b0;
else
if( eop_r) //disable on any EOP
receiver_enabled <= 1'b0;
else
if( dp_input[0] ) //enable receiver on raising edge of DP line
receiver_enabled <= enable;
//change on DP line defines strobing
wire dp_change;
assign dp_change = dp_input[0] ^ dp_input[1];
//generate clocked receiver strobe with this counter
reg [2:0]clk_counter;
always @(posedge clk or posedge reset )
begin
if(reset)
clk_counter <= 3'b000;
else
begin
//every edge on line resynchronizes receiver clock
if(dp_change | eop_r)
clk_counter <= 3'b000;
else
clk_counter <= clk_counter + 1'b1;
end
end
reg r_strobe;
always @*
r_strobe = (clk_counter == 3'b011) & receiver_enabled;
//on receiver strobe remember last fixed DP value
reg last_fixed_dp;
always @(posedge clk or posedge reset)
begin
if(reset)
last_fixed_dp <= 1'b0;
else
begin
if(r_strobe | eop_r)
begin
last_fixed_dp <= dp_input[1] & (~eop_r);
end
end
end
//count number of sequental ones for bit staffling
reg [2:0]num_ones;
always @(posedge clk or posedge reset)
begin
if(reset)
num_ones <= 3'b000;
else
begin
if(r_strobe)
begin
if(last_fixed_dp == dp_input[1])
num_ones <= num_ones + 1'b1;
else
num_ones <= 3'b000;
end
end
end
//flag which mean that zero should be removed from bit stream because of bitstuffling
wire do_remove_zero; assign do_remove_zero = (num_ones == 6);
//receiver process
always @(posedge clk or posedge reset )
begin
if(reset)
begin
//kind of reset
receiver_cnt <= 0;
rdata <= 0;
rdata_ready <= 1'b0;
end
else
begin
if(r_strobe & (!do_remove_zero) | eop_r)
begin
//decode NRZI
//shift-in ONE if older and new values are same
//shift-in ZERO if older and new values are different
//BUT (bitstuffling) do not shift-in one ZERO after 6 ONEs
if(eop_r)
begin
receiver_cnt <= 0;
rdata <= 0;
end
else
begin
receiver_cnt <= receiver_cnt + 1'b1;
rdata <= { (last_fixed_dp == dp_input[1]) , rdata[7:1]};
end
end
//set write-enable signal (write into receiver buffer)
rdata_ready <= (receiver_cnt == 7) & r_strobe & (!do_remove_zero) & (~eop_r);
end
end
//count number of received bytes
always @(posedge clk or posedge reset )
begin
if(reset)
rbyte_cnt <= 0;
else
begin
if(eop_rfe)
rbyte_cnt <= 0;
else
if(rdata_ready)
rbyte_cnt <= rbyte_cnt + 1'b1;
end
end
endmodule

216
fpga/rtl/usbhost/ls_usb_send.v Executable file
View File

@ -0,0 +1,216 @@
//low speed USB send function
module ls_usb_send(
input wire reset,
//clock should be 12Mhz
input wire clk,
input wire bit_impulse,
input wire eof,
input wire [7:0]sbyte, //byte for send
input wire start_pkt, //start sending packet on that signal
input wire last_pkt_byte, //mean send EOP at the end
//received from host
input wire cmd_reset,
input wire cmd_enable,
//usb BUS signals
output reg dp,
output reg dm,
output reg bus_enable,
//usb BUS signals for
output reg show_next, //request for next sending byte in packet
output reg pkt_end //mean that packet was sent
);
reg sbit;
reg se0;
always @*
begin
sbit = (prev_sbit ^ (!send_reg[0]) ^ (six_ones & send_reg[0])) & bus_ena_pkt;
se0 = !(bus_ena_pkt ^ (bus_ena_pkt | bus_ena_prev[1]));
show_next = (bit_count==3'h7) & sending_bit & bus_ena_pkt & (!last);
pkt_end = bus_enable & (!bus_ena_pkt) & (bit_count==3'h3) & bit_impulse;
end
//USB Reset and USB Enable become actual with frame start only
reg usb_reset_fixed;
reg usb_enable_fixed;
always @(posedge clk or posedge reset)
begin
if(reset)
begin
usb_reset_fixed <= 1'b0;
usb_enable_fixed <= 1'b0;
end
else
if(eof)
begin
usb_reset_fixed <= cmd_reset;
usb_enable_fixed <= cmd_enable;
end
end
//bus enable signal, which is related to packet sending
reg bus_ena_pkt;
always @(posedge clk or posedge reset)
begin
if(reset)
bus_ena_pkt <= 1'b0;
else
begin
if(start_pkt)
bus_ena_pkt <= 1'b1;
else
if( sending_last_bit & last | eof)
bus_ena_pkt <= 1'b0;
end
end
//delay shift register for bus enable for packet
reg [2:0]bus_ena_prev;
always @(posedge clk or posedge reset)
begin
if(reset)
bus_ena_prev <= 3'b000;
else
if(bit_impulse)
bus_ena_prev <= {bus_ena_prev[1:0],bus_ena_pkt};
end
reg eof_f;
always @(posedge clk or posedge reset)
if(reset)
eof_f <= 1'b0;
else
if(bit_impulse)
eof_f <= eof;
//bus enable generation
always @(posedge clk or posedge reset)
if(reset)
bus_enable <= 1'b0;
else
if(bit_impulse)
bus_enable <= ((bus_ena_pkt | bus_ena_prev[2]))
| usb_reset_fixed //bus enabled when reset
| (usb_enable_fixed & (eof|eof_f) ); //bus enabled for keep-alive messages
wire suppress; assign suppress = usb_reset_fixed | (usb_enable_fixed & eof);
//make output on USB buses
always @(posedge clk or posedge reset)
if(reset)
begin
dp <= 1'b0;
dm <= 1'b0;
end
else
if(bit_impulse)
begin
dp <= suppress ? 1'b0 : ( sbit & se0 );
dm <= suppress ? 1'b0 : ((!sbit) & se0 );
end
//count number of sequental ONEs
reg [2:0]ones_cnt;
wire six_ones; assign six_ones = (ones_cnt==3'h6);
wire sending_bit = bit_impulse & (!six_ones);
always @(posedge clk or posedge reset)
begin
if(reset)
ones_cnt <= 0;
else
begin
if(eof)
ones_cnt <= 0;
else
if(bit_impulse & bus_ena_pkt)
begin
if(sbit==prev_sbit)
ones_cnt <= ones_cnt+1'b1;
else
ones_cnt <= 0;
end
end
end
//fix just sent bit
reg prev_sbit;
always @(posedge clk or posedge reset)
begin
if(reset)
prev_sbit <= 1'b0;
else
begin
if( start_pkt )
prev_sbit <= 1'b0;
else
if(bit_impulse & bus_ena_pkt )
prev_sbit <= sbit;
end
end
//fix flag about last byte in packet
reg last;
always @(posedge clk or posedge reset)
begin
if(reset)
last <= 1'b0;
else
begin
if( start_pkt )
last <= 1'b0;
else
if(sending_last_bit)
last <= last_pkt_byte;
end
end
//count number of sent bits
reg [2:0]bit_count;
always @(posedge clk or posedge reset)
begin
if(reset)
bit_count <= 3'b000;
else
begin
if( start_pkt )
bit_count <= 3'b000;
else
if( sending_bit)
bit_count <= bit_count + 1'b1;
end
end
wire bit_count_eq7; assign bit_count_eq7 = (bit_count==3'h7);
wire sending_last_bit = sending_bit & bit_count_eq7; //sending last bit in byte
//load/shift sending register
reg [7:0]send_reg;
always @(posedge clk or posedge reset)
begin
if(reset)
send_reg <= 0;
else
begin
if(eof)
send_reg <= 0;
else
if(sending_bit | start_pkt)
begin
if(bit_count_eq7 | start_pkt)
send_reg <= sbyte; //load first or next bytes for send
else
send_reg <= {1'b0, send_reg[7:1]}; //shift out byte
end
end
end
endmodule

124
fpga/rtl/usbhost/serial.v Executable file
View File

@ -0,0 +1,124 @@
module serial(
input wire reset,
input wire clk100, //96MHz
input wire rx,
input wire [7:0]sbyte,
input wire send,
output reg [7:0]rx_byte,
output reg rbyte_ready,
output reg rbyte_ready2, //long variant of rbyte_ready
output reg tx,
output reg busy,
output wire [7:0]rb
);
parameter RCONST = 104; // 96000000Hz / 921600bps = 104
assign rb = {1'b0,rx_byte[7:1]};
reg [1:0]shr;
always @(posedge clk100)
shr <= {shr[0],rx};
wire rxf; assign rxf = shr[1];
reg [15:0]cnt;
reg [3:0]num_bits;
always @(posedge clk100 or posedge reset)
begin
if(reset)
cnt <= 0;
else
begin
if(cnt == RCONST || num_bits==10)
cnt <= 0;
else
cnt <= cnt + 1'b1;
end
end
reg [7:0]shift_reg;
always @(posedge clk100 or posedge reset)
begin
if(reset)
begin
num_bits <= 0;
shift_reg <= 0;
end
else
begin
if(num_bits==10 && rxf==1'b0)
num_bits <= 0;
else
if(cnt == RCONST)
num_bits <= num_bits + 1'b1;
if( cnt == RCONST/2 )
shift_reg <= {rxf,shift_reg[7:1]};
end
end
always @(posedge clk100 or posedge reset)
if(reset)
begin
rx_byte <= 0;
end
else
begin
if(num_bits==9 && cnt == RCONST/2)
rx_byte <= shift_reg[7:0];
end
always @(posedge clk100 or posedge reset)
if( reset )
rbyte_ready <= 1'b0;
else
rbyte_ready <= (num_bits==9 && cnt == RCONST/2);
reg [8:0]send_reg;
reg [3:0]send_num;
reg [15:0]send_cnt;
wire send_time; assign send_time = send_cnt == RCONST;
always @(posedge clk100 or posedge reset)
begin
if(reset)
begin
send_reg <= 9'h1FF;
send_num <= 10;
send_cnt <= 0;
end
else
begin
if(send)
send_cnt <= 0;
else
if(send_time)
send_cnt <= 0;
else
send_cnt <= send_cnt + 1'b1;
if(send)
begin
send_reg <= {sbyte,1'b0};
send_num <= 0;
end
else
if(send_time && send_num!=10)
begin
send_reg <= {1'b1,send_reg[8:1]};
send_num <= send_num + 1'b1;
end
end
end
always @*
begin
busy = send_num!=10;
tx = send_reg[0];
end
endmodule

167
fpga/rtl/usbhost/tb.v Executable file
View File

@ -0,0 +1,167 @@
`timescale 1ns / 1ns
module tb;
//usb clock ~12MHz
reg clock12 = 1'b0;
always #42
clock12 = ~clock12;
//system clock
reg clock = 1'b0;
always #5
clock = ~clock;
reg reset=1'b0;
wire idp;
wire idm;
reg [7:0]cmd=8'h00;
reg cmd_wr=1'b0;
wire odp, odm, ooe;
wire [7:0]rdata;
reg rdata_rd=1'b0;
wire w_rd;
usbhost usbhost_(
.rst( reset ),
.iclk( clock ), //interface clk
.wdata( cmd ), //interface commands and data
.wr( cmd_wr ), //write
.wr_level(),
.rdata( rdata ),//result data
.rd( w_rd ),//read
.rdata_ready( w_rd ),
.cclk( clock12 ), //core clock, 12MHz
.i_dp( idp ),
.i_dm( idm ),
.o_dp( odp ),
.o_dm( odm ),
.o_oe( ooe )
);
reg [31:0] cmd_time [0:255];
reg [ 7:0] cmd_val [0:255];
reg [7:0]idx;
initial
begin
idx=0;
cmd_time[idx]=100; cmd_val[idx]=8'h01; idx=idx+1; //get lines
cmd_time[idx]=200; cmd_val[idx]=8'h32; idx=idx+1; //reset
cmd_time[idx]=199130; cmd_val[idx]=8'h22; idx=idx+1; //enable
cmd_time[idx]=203200; cmd_val[idx]=8'h03; idx=idx+1; //wait eof
cmd_time[idx]=203201; cmd_val[idx]=8'h03; idx=idx+1; //wait eof
cmd_time[idx]=203202; cmd_val[idx]=8'h44; idx=idx+1; //send pkt
cmd_time[idx]=203203; cmd_val[idx]=8'h80; idx=idx+1;
cmd_time[idx]=203204; cmd_val[idx]=8'h2d; idx=idx+1;
cmd_time[idx]=203205; cmd_val[idx]=8'h00; idx=idx+1;
cmd_time[idx]=203206; cmd_val[idx]=8'h10; idx=idx+1;
cmd_time[idx]=203207; cmd_val[idx]=8'he4; idx=idx+1; //send pkt
cmd_time[idx]=203208; cmd_val[idx]=8'h80; idx=idx+1;
cmd_time[idx]=203209; cmd_val[idx]=8'hC4; idx=idx+1;
cmd_time[idx]=203210; cmd_val[idx]=8'h80; idx=idx+1;
cmd_time[idx]=203211; cmd_val[idx]=8'hc3; idx=idx+1;
cmd_time[idx]=203212; cmd_val[idx]=8'h80; idx=idx+1;
cmd_time[idx]=203213; cmd_val[idx]=8'h06; idx=idx+1;
cmd_time[idx]=203214; cmd_val[idx]=8'h00; idx=idx+1;
cmd_time[idx]=203215; cmd_val[idx]=8'h01; idx=idx+1;
cmd_time[idx]=203216; cmd_val[idx]=8'h00; idx=idx+1;
cmd_time[idx]=203217; cmd_val[idx]=8'h00; idx=idx+1;
cmd_time[idx]=203218; cmd_val[idx]=8'h40; idx=idx+1;
cmd_time[idx]=203219; cmd_val[idx]=8'h00; idx=idx+1;
cmd_time[idx]=203220; cmd_val[idx]=8'hdd; idx=idx+1;
cmd_time[idx]=203221; cmd_val[idx]=8'h94; idx=idx+1;
cmd_time[idx]=203222; cmd_val[idx]=8'h05; idx=idx+1;
cmd_time[idx]=203225; cmd_val[idx]=8'h06; idx=idx+1;
idx=0;
end
reg [32:0]counter=0;
always @(posedge clock)
begin
counter<=counter+1;
if( counter==cmd_time[idx] )
begin
cmd <= cmd_val[idx];
cmd_wr<=1'b1;
idx<=idx+1;
end
else
begin
cmd <= 0;
cmd_wr<=1'b0;
end
end
always @( posedge usbhost_.bit_impulse )
if( usbhost_.bit_time==300)
$dumpoff;
else
if( usbhost_.bit_time==1450)
$dumpon;
wire [7:0]w_send_byte;
wire w_start_pkt;
wire w_last;
wire w_show_next;
wire w_pkt_end;
ls_usb_send ls_usb_send_(
.reset( reset ),
.clk( clock12 ),
.bit_impulse( usbhost_.bit_impulse ),
.eof( usbhost_.eof ),
.sbyte( w_send_byte ), //byte for send
.start_pkt( w_start_pkt ), //start sending packet on that signal
.last_pkt_byte( w_last ), //mean send EOP at the end
.cmd_reset( 1'b0 ),
.cmd_enable( 1'b1 ),
.dp( idp ),
.dm( idm ),
.bus_enable( ),
.show_next( w_show_next ), //request for next sending byte in packet
.pkt_end( w_pkt_end ) //mean that packet was sent
);
reg [7:0]send_state = 0;
always @(posedge clock12)
if( send_state==0 && usbhost_.enable_recv )
send_state<=1;
else
if( send_state==1)
send_state<=2;
else
if( send_state==2 && w_show_next )
send_state<=3;
else
if( send_state==3 && w_show_next )
send_state<=4;
else
if( send_state==4 && w_show_next )
send_state<=5;
assign w_start_pkt = (send_state==1);
assign w_send_byte = (send_state==1) ? 8'h80 :
(send_state==2) ? 8'hA5 :
(send_state==3) ? 8'h73 :
(send_state==4) ? 8'h23 :
(send_state==5) ? 8'h11 : 0;
assign w_last = (send_state==4);
initial
begin
$dumpfile("out.vcd");
$dumpvars(0,tb);
reset = 1'b1;
#500;
reset = 1'b0;
#6000000;
$finish();
end
endmodule

391
fpga/rtl/usbhost/usbhost.v Executable file
View File

@ -0,0 +1,391 @@
module usbhost(
//interface
input wire rst,
input wire iclk, //interface clk
input wire [7:0]wdata, //interface commands and data
input wire wr, //write
output wire [1:0]wr_level,
output wire [7:0]rdata, //result data
input wire rd, //read
output wire rdata_ready,
//core
input wire cclk, //core clock, 12MHz
input wire i_dp,
input wire i_dm,
output wire o_dp,
output wire o_dm,
output wire o_oe,
output wire [7:0]leds
);
//controller serial bytes protocol
localparam CMD_GET_LINES = 4'h1; //controller must once poll and return one byte state of USB lines
localparam CMD_BUS_CTRL = 4'h2; //controller must set bus to reset/normal and/or or enabled/disabled state
//reset state - dm/dm in zero
//enabled state when no reset and 1ms periodic SE0 impulses go
localparam CMD_WAIT_EOF = 4'h3; //controller just waits EOF/SE0 condition
//any bus operation should start from this, so any read/write start //at begin of frame
localparam CMD_SEND_PKT = 4'h4; //new packed will be sent to bus. high 4 bits of cmd byte mean data length
localparam CMD_READ_PKT = 4'h5;
localparam CMD_AUTO_ACK = 4'h6;
//controller state machine states
localparam STATE_IDLE = 0;
localparam STATE_READ_CMD = 1;
localparam STATE_GOT_CMD = 2;
localparam STATE_READ_LINES = 3;
localparam STATE_BUS_CONTROL = 4;
localparam STATE_WAIT_EOF = 5;
localparam STATE_WAIT_NO_EOF = 6;
localparam STATE_WAIT_BIT0 = 7;
localparam STATE_WAIT_BIT1 = 8;
localparam STATE_FETCH_SEND_BYTE = 9;
localparam STATE_CATCH_SEND_BYTE = 10;
localparam STATE_FETCH_SEND_BYTE1 = 11;
localparam STATE_CATCH_SEND_BYTE1 = 12;
localparam STATE_SENDING = 13;
localparam STATE_WAIT_ACK = 14;
localparam STATE_READ_DATA = 15;
localparam STATE_READ_DATA_ALL = 16;
localparam STATE_COPY_TMP_PKT = 17;
localparam STATE_COPY_TMP_PKT2 = 18;
localparam STATE_SEND_ACK_WAIT_BIT0 = 19;
localparam STATE_SEND_ACK_WAIT_BIT1 = 20;
localparam STATE_SEND_ACK_80 = 21;
localparam STATE_SEND_ACK_D2 = 22;
reg [7:0]state = 0;
//make low speed bit impulse
reg [2:0]cnt;
reg bit_impulse;
always @( posedge cclk or posedge rst )
begin
if(rst)
begin
cnt <= 0;
bit_impulse <= 0;
end
else
begin
cnt <= cnt + 1;
bit_impulse <= (cnt==7);
end
end
//make frame EOF impulse
reg eof;
reg [10:0]bit_time;
always @(posedge cclk or posedge rst)
begin
if(rst)
begin
bit_time <= 0;
eof <= 1'b0;
end
else
begin
if(bit_impulse)
begin
if(bit_time==1499)
bit_time <= 0;
else
bit_time <= bit_time + 1'b1;
end
eof <= (bit_time > 1497 );
end
end
wire in_empty;
wire [1:0]in_rd_level;
wire [7:0]in_cmd;
reg in_rd=1'b0;
//input data and commands go into FIFO
generic_fifo_dc_gray #( .dw(8), .aw(6) ) fifo_in(
.rst( ~rst ),
.rd_clk( cclk ),
.wr_clk( iclk ),
.clr( 1'b0 ),
.din( wdata ),
.we( wr ),
.dout( in_cmd ),
.rd( in_rd ),
.full(),
.empty( in_empty ),
.wr_level( wr_level ),
.rd_level( in_rd_level )
);
assign leds = in_cmd;
//result data go to output FIFO
wire [7:0]out_data;
wire out_data_wr;
wire empty;
assign rdata_ready = ~empty;
generic_fifo_dc_gray #( .dw(8), .aw(4) ) fifo_out(
.rst( ~rst ),
.rd_clk( iclk ),
.wr_clk( cclk ),
.clr( 1'b0 ),
.din( out_data ),
.we( out_data_wr ),
.dout( rdata ),
.rd( rd ),
.full(),
.empty( empty ),
.wr_level( ),
.rd_level( )
);
wire [7:0]usb_rdata;
wire usb_rdata_ready;
wire eop_r;
wire enable_recv;
//Need temporary fifo to store USB packet received from USB bus.
//When USB packet received, then we know actual packet length and then
//we can copy temporary data into output fifo, but first in protocol go packet length encoded with command
wire [7:0]tmp_fifo_data;
wire tmp_fifo_rd; assign tmp_fifo_rd = (~tmp_fifo_empty) & (state==STATE_COPY_TMP_PKT);
wire tmp_fifo_empty;
generic_fifo_dc_gray #( .dw(8), .aw(4) ) fifo_out_tmp(
.rst( ~rst ),
.rd_clk( cclk ),
.wr_clk( cclk ),
.clr( state==STATE_READ_DATA ), //reset tmp fifo at begin of any recv packet
.din( usb_rdata ),
.we( usb_rdata_ready ),
.dout( tmp_fifo_data ),
.rd( tmp_fifo_rd ),
.full(),
.empty( tmp_fifo_empty ),
.wr_level( ),
.rd_level( )
);
assign out_data =
(state==STATE_READ_LINES) ? { 2'b00, i_dp, i_dm, CMD_GET_LINES }:
( (state==STATE_READ_DATA_ALL) & got_recv_pkt_length) ? { usb_rbyte_cnt, CMD_READ_PKT }:
tmp_fifo_data;
assign out_data_wr =
(state==STATE_READ_LINES) |
((state==STATE_READ_DATA_ALL) & got_recv_pkt_length) |
(state==STATE_COPY_TMP_PKT & (~tmp_fifo_empty) );
assign enable_recv = (state==STATE_READ_DATA) | (state==STATE_READ_DATA_ALL);
always @*
in_rd = (state==STATE_READ_CMD) || (state==STATE_FETCH_SEND_BYTE) || (state==STATE_FETCH_SEND_BYTE1);
reg cmd_ready=1'b0;
always @( posedge cclk )
cmd_ready <= in_rd;
reg [7:0]in_cmd_;
always @( posedge cclk )
if( cmd_ready && state==STATE_GOT_CMD )
in_cmd_ <= in_cmd;
reg [7:0]send_byte;
always @( posedge cclk )
if( cmd_ready && (state==STATE_CATCH_SEND_BYTE || state==STATE_CATCH_SEND_BYTE1) )
send_byte <= in_cmd;
reg bus_reset;
reg bus_enable;
always @( posedge cclk or posedge rst )
begin
if(rst)
begin
bus_reset <= 1'b0;
bus_enable <= 1'b0;
end
else
if( state==STATE_BUS_CONTROL )
begin
bus_reset <= in_cmd_[4];
bus_enable <= in_cmd_[5];
end
end
always @( posedge cclk )
begin
case( state )
STATE_IDLE: begin
if( ~in_empty )
state <= STATE_READ_CMD;
end
STATE_READ_CMD: begin
state <= STATE_GOT_CMD;
end
STATE_GOT_CMD: begin
case( in_cmd[3:0] )
CMD_GET_LINES: state <= STATE_READ_LINES;
CMD_BUS_CTRL: state <= STATE_BUS_CONTROL;
CMD_WAIT_EOF: state <= STATE_WAIT_EOF;
CMD_SEND_PKT: state <= STATE_WAIT_BIT0;
CMD_READ_PKT: state <= STATE_READ_DATA;
CMD_AUTO_ACK: state <= STATE_SEND_ACK_WAIT_BIT0;
default:
state <= STATE_IDLE;
endcase
end
STATE_READ_LINES: begin
state <= STATE_IDLE;
end
STATE_BUS_CONTROL: begin
state <= STATE_IDLE;
end
STATE_WAIT_EOF: begin
if( bit_impulse & eof )
state <= STATE_WAIT_NO_EOF;
end
STATE_WAIT_NO_EOF: begin
if( bit_impulse & (~eof) )
state <= STATE_IDLE;
end
STATE_WAIT_BIT0: begin
if( bit_impulse &(~eof) )
state <= STATE_WAIT_BIT1;
end
STATE_WAIT_BIT1: begin
if( bit_impulse )
state <= STATE_FETCH_SEND_BYTE;
end
STATE_FETCH_SEND_BYTE: begin
state <= STATE_CATCH_SEND_BYTE;
end
STATE_CATCH_SEND_BYTE: begin
if( start_pkt)
state <= STATE_FETCH_SEND_BYTE1;
end
STATE_FETCH_SEND_BYTE1: begin
state <= STATE_CATCH_SEND_BYTE1;
end
STATE_CATCH_SEND_BYTE1: begin
state <= STATE_SENDING;
end
STATE_SENDING: begin
if( show_next & num_bytes_sent<in_cmd_[7:4])
state <= STATE_FETCH_SEND_BYTE1;
else
if( pkt_end )
state <= STATE_IDLE;
end
STATE_SEND_ACK_WAIT_BIT0: begin
//here we may decide to ACK or not to ACK and got to STATE_IDLE..
//if recent received byte is 0x5A(NAK) then no need to auto-ACK
if( last_recv_byte==8'h5A )
state <= STATE_IDLE;
else
if( bit_impulse )
state <= STATE_SEND_ACK_WAIT_BIT1;
end
STATE_SEND_ACK_WAIT_BIT1: begin
if( bit_impulse )
state <= STATE_SEND_ACK_80;
end
STATE_SEND_ACK_80: begin
state <= STATE_SEND_ACK_D2;
end
STATE_SEND_ACK_D2: begin
if(show_next)
state <= STATE_IDLE;
end
STATE_WAIT_ACK: begin
state <= STATE_IDLE;
end
STATE_READ_DATA: begin
state <= STATE_READ_DATA_ALL;
end
STATE_READ_DATA_ALL: begin
if( eof | eop_r )
state <= STATE_COPY_TMP_PKT;
end
STATE_COPY_TMP_PKT: begin
state <= STATE_COPY_TMP_PKT2;
end
STATE_COPY_TMP_PKT2: begin
if( tmp_fifo_empty )
state <= STATE_IDLE;
else
state <= STATE_COPY_TMP_PKT;
end
endcase
end
reg [3:0]num_bytes_sent;
always @( posedge cclk )
if( state==STATE_GOT_CMD )
num_bytes_sent<= 1;
else
if( start_pkt | show_next )
num_bytes_sent <= num_bytes_sent+1;
wire start_pkt; assign start_pkt = (state==STATE_CATCH_SEND_BYTE) & bit_impulse;
wire pkt_end;
wire [7:0]actual_send_byte;
assign actual_send_byte =
(state==STATE_SEND_ACK_80) ? 8'h80 : //maybe auto-ack or real data from SW
(state==STATE_SEND_ACK_D2) ? 8'hD2 : send_byte;
wire actual_start_pkt;
assign actual_start_pkt = start_pkt | (state==STATE_SEND_ACK_80);
wire actual_last_pkt_byte;
assign actual_last_pkt_byte = (num_bytes_sent==in_cmd_[7:4]) | (state==STATE_SEND_ACK_D2);
wire show_next;
ls_usb_send ls_usb_send_(
.reset( rst ),
.clk( cclk ),
.bit_impulse( bit_impulse ),
.eof( eof ),
.sbyte( actual_send_byte ), //byte for send
.start_pkt( actual_start_pkt ), //start sending packet on that signal
.last_pkt_byte( actual_last_pkt_byte ), //mean send EOP at the end
.cmd_reset( bus_reset ),
.cmd_enable( bus_enable ),
.dp( o_dp ),
.dm( o_dm ),
.bus_enable( o_oe ),
.show_next( show_next ), //request for next sending byte in packet
.pkt_end( pkt_end ) //mean that packet was sent
);
wire [3:0]usb_rbyte_cnt;
ls_usb_recv ls_usb_recv_(
.reset( rst ),
.clk( cclk ),
.dp( i_dp ),
.dm( i_dm ),
.enable( enable_recv ),
.eop_r( eop_r ),
.rdata( usb_rdata ),
.rdata_ready( usb_rdata_ready ),
.rbyte_cnt( usb_rbyte_cnt ),
.eop_rfe( )
);
reg [7:0]last_recv_byte;
always @(posedge cclk)
if(usb_rdata_ready)
last_recv_byte <= usb_rdata;
reg eop_r_;
always @(posedge cclk)
eop_r_ <= eop_r;
wire got_recv_pkt_length;
assign got_recv_pkt_length = ((eop_r_==1'b0) && (eop_r==1'b1));
endmodule

84
fpga/rtl/util.vh Executable file
View File

@ -0,0 +1,84 @@
`define MAX(a,b) (a)>(b)?(a):(b)
`define MIN(a,b) (a)<(b)?(a):(b)
`define ISDEF(N) (^(N) >= 0 === 1'b1 || ^(N) < 0 === 1'b1) //"IS DEFined", is an
//integer strictly defined; Xilinx warnings about "===" in synthesable
//code - include in supression rules.
//Why so complicated - I forgot :)
`define TZER(N) (!`ISDEF(N) || (N) <= 0) ? 'hx : \
(~|((N)&'h7fff_ffff)?31:(~|((N)&'h3fff_ffff)?30: \
(~|((N)&'h1fff_ffff)?29:(~|((N)&'hfff_ffff)?28: \
(~|((N)&'h7ff_ffff)?27:(~|((N)&'h3ff_ffff)?26:(~|((N)&'h1ff_ffff)?25:(~|((N)&'hff_ffff)?24: \
(~|((N)&'h7f_ffff)?23:(~|((N)&'h3f_ffff)?22:(~|((N)&'h1f_ffff)?21:(~|((N)&'hf_ffff)?20: \
(~|((N)&'h7_ffff)?19:(~|((N)&'h3_ffff)?18:(~|((N)&'h1_ffff)?17:(~|((N)&'hffff)?16: \
(~|((N)&'h7fff)?15:(~|((N)&'h3fff)?14:(~|((N)&'h1fff)?13:(~|((N)&'hfff)?12: \
(~|((N)&'h7ff)?11:(~|((N)&'h3ff)?10:(~|((N)&'h1ff)?9:(~|((N)&'hff)?8: \
(~|((N)&'h7f)?7:(~|((N)&'h3f)?6:(~|((N)&'h1f)?5:(~|((N)&'hf)?4: \
(~|((N)&'h7)?3:(~|((N)&'h3)?2: \
(~N&'h1))))))))))))))))))))))))))))))) //"Trailong ZERoes". ONLY FOR ARGUMENTS <= 32 BITS!
//Maximum 2's power divider of a number. Both for synthesis and simulation; bit
//selection is not used since N could be an expression.
`define CLOG2_CORE(N) \
((N)&'h8000_0000 ?32:((N)&'h4000_0000 ?31:((N)&'h2000_0000 ?30:((N)&'h1000_0000 ?29: \
((N)&'h800_0000 ?28:((N)&'h400_0000 ?27:((N)&'h200_0000 ?26:((N)&'h100_0000 ?25: \
((N)&'h80_0000 ?24:((N)&'h40_0000 ?23:((N)&'h20_0000 ?22:((N)&'h10_0000 ?21: \
((N)&'h8_0000 ?20:((N)&'h4_0000 ?19:((N)&'h2_0000 ?18:((N)&'h1_0000 ?17: \
((N)&'h8000 ?16:((N)&'h4000 ?15:((N)&'h2000 ?14:((N)&'h1000 ?13: \
((N)&'h800 ?12:((N)&'h400 ?11:((N)&'h200 ?10:((N)&'h100 ?9: \
((N)&'h80 ?8:((N)&'h40 ?7:((N)&'h20 ?6:((N)&'h10 ?5: \
((N)&'h8 ?4:((N)&'h4 ?3:((N)&'h2 ?2: \
((N)&'h1)))))))))))))))))))))))))))))))) //"Core Ceil(LOG2(N+1))" for correctly defined
//values (<= 32 bits). Both for synthesis and not; bit selection is not
//used since N could be an expression.
`define HZ2NS(F) (1.0e9 / (F)) //Convert frequency [Hz] to delay in [ns].
`define ABS(X) ((X >= 0) ? (X) : (-X)) //ABSolute value of X.
`define CLOG2(N) ((!`ISDEF(N) || (N) <= 0) ? 'hx : `CLOG2_CORE((N)-1)) //"Ceil(LOG2(N))"
//ONLY FOR ARGUMENTS <= 32 BITS! Ceil (nearest greater or equal integer) of
//binary logarithm.
`define WIDINPAR(W) ((W) >= 1 ? (W) : ((W) == 0 ? 1'b1 : 1'bx)) //"WIDth INdex from a
//PARameter" ONLY FOR ARGUMENTS <= 32 BITS! High index of a bus from given
//parameter, to avoid index "-1".
//Ex.: bus with width W: "[widinpar(W)-1:0];"
`define WIDC(N) (`ISDEF(N) && (N) == 0 ? 1 : `CLOG2((N) + 1)) //"WIDth Computation"
//ONLY FOR ARGUMENTS <= 32 BITS! High index of a bus out of it's maximum
//value (from 0).
//Ex.: bus for holding numbers in range [0..N]: "wire [`WIDCF(N)-1:0] bus;"
//Precision width of parameters: "localparam [`WIDCF(<expr>)-1:0] N = <expr>;"
`define WIDCN(N) (`ISDEF(N) && ((N) == 0 || (N) == 1) ? 1 : `CLOG2(N)) //"WIDth Computation from N"
//ONLY FOR ARGUMENTS <= 32 BITS! High index of a bus out of number of it's
//different values. Handy for computation of high index of a bus.
//Ex.: coder with N inputs output: "output [`WIDCFN(N)-1:0] out;";
//N-words RAM adress input: "input [`WIDCFN(N)-1:0] adr;"
`define URAND(MIN, MAX) ((MAX) < (MIN) ? 1'bx : (((MAX) == (MIN)) ? (MIN) : \
(MIN + {$random} % ((MAX) - (MIN)))) )
//Form an unsigned random value in the range [MIN..MAX-1];
//"{}" makes unsigned.
`define POS_FMOD(A, B) A - B * ($rtoi((A + 0.0) / B) + $signed(A < 0)) //Positive fraction
//modulo. Only for POSITIVE dividers!!!
`define ISHEXD(L) (`ISDEF(L) && ((L) >= "A" && (L) <= "F" || (L) >= "a" && (L) <= "f" || \
(L) >= "0" && (L) <= "9")) //IS byte a HEX Digit. x- and z-
//bits are treated correctly.
`define ISHEXDX(L) (`ISHEXD(L) || \
`ISDEF(L) && ((L) == "X" || (L) == "x")) //IS byte a HEX Digit or X/x.
`define IS_DEC_INT_DIG(L) ((L) >= "0" && (L) <= "9") //Is a byte a valid decimal
//integer digit.
`define HEXD2DEC(L) (!`ISHEXD(L) ? \
0 : \
((L) >= "a" ? (L) - "a" + 10 : \
((L) >= "A" ? (L) - "A" + 10 : \
(L) - "0"))) //Convert
//HEXadecimal Digit to decimal number, on all incorrect inputs returns 0.

543
fpga/rtl/ym2149.vhd Executable file
View File

@ -0,0 +1,543 @@
--
-- A simulation model of YM2149 (AY-3-8910 with bells on)
--
-- Copyright (c) MikeJ - Jan 2005
--
-- All rights reserved
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- Neither the name of the author nor the names of other contributors may
-- be used to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS CODE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
-- You are responsible for any legal issues arising from your use of this code.
--
-- The latest version of this file can be found at: www.fpgaarcade.com
--
-- Email support@fpgaarcade.com
--
-- Revision list
--
-- version 001 initial release
--
-- Clues from MAME sound driver and Kazuhiro TSUJIKAWA
--
-- These are the measured outputs from a real chip for a single Isolated channel into a 1K load (V)
-- vol 15 .. 0
-- 3.27 2.995 2.741 2.588 2.452 2.372 2.301 2.258 2.220 2.198 2.178 2.166 2.155 2.148 2.141 2.132
-- As the envelope volume is 5 bit, I have fitted a curve to the not quite log shape in order
-- to produced all the required values.
-- (The first part of the curve is a bit steeper and the last bit is more linear than expected)
--
-- Modifications made for the ZX Spectrum Next Project
-- <https://gitlab.com/SpectrumNext/ZX_Spectrum_Next_FPGA/tree/master/cores>
--
-- 1. Bus addressing moved out of module
-- 2. Channel mixing moved out of module
-- 3. Eliminate unnecessary busctrl_re
-- 4. Make zero volume actually zero volume in the tables.
-- (Not how the real hw works but it makes audio out of the zx next cleaner)
-- 5. Add differences in how registers are read back on YM and AY
-- 6. Fix bug where envelope period counter was not reset on envelope reset
-- 7. Export currently selected register
library ieee;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity YM2149 is
generic (
constant AY_ID : std_logic_vector(1 downto 0) := "00"
);
port (
CLK : in std_logic; -- note 6 Mhz
ENA : in std_logic; -- clock enable for higher speed operation
RESET_H : in std_logic;
I_SEL_L : in std_logic;
-- data bus
I_DA : in std_logic_vector(7 downto 0);
O_DA : out std_logic_vector(7 downto 0);
I_REG : in std_logic;
-- control
busctrl_addr : in std_logic;
busctrl_we : in std_logic;
ctrl_aymode : in std_logic; -- 0 = YM, 1 = AY
-- I/O ports
port_a_i : in std_logic_vector(7 downto 0);
port_a_o : out std_logic_vector(7 downto 0);
port_b_i : in std_logic_vector(7 downto 0);
port_b_o : out std_logic_vector(7 downto 0);
-- audio channels out
O_AUDIO_A : out std_logic_vector(7 downto 0);
O_AUDIO_B : out std_logic_vector(7 downto 0);
O_AUDIO_C : out std_logic_vector(7 downto 0)
);
end;
architecture RTL of YM2149 is
-- signals
type array_16x8 is array (0 to 15) of std_logic_vector(7 downto 0);
type array_3x12 is array (1 to 3) of std_logic_vector(11 downto 0);
signal cnt_div : std_logic_vector(3 downto 0) := (others => '0');
signal noise_div : std_logic := '0';
signal ena_div : std_logic;
signal ena_div_noise : std_logic;
signal noise_gen_comp : std_logic_vector(4 downto 0);
signal poly17_zero : std_logic;
signal poly17 : std_logic_vector(16 downto 0) := (others => '0');
-- registers
signal addr : std_logic_vector(4 downto 0);
signal reg : array_16x8;
signal env_reset : std_logic;
signal noise_gen_cnt : std_logic_vector(4 downto 0);
signal noise_gen_op : std_logic;
signal tone_gen_freq : array_3x12;
signal tone_gen_comp : array_3x12;
signal tone_gen_cnt : array_3x12 := (others => (others => '0'));
signal tone_gen_op : std_logic_vector(3 downto 1) := "000";
signal is_zero : std_logic;
signal is_ones : std_logic;
signal is_bot : std_logic;
signal is_bot_p1 : std_logic;
signal is_top_m1 : std_logic;
signal is_top : std_logic;
signal env_gen_freq : std_logic_vector(15 downto 0);
signal env_gen_comp : std_logic_vector(15 downto 0);
signal env_gen_cnt : std_logic_vector(15 downto 0);
signal env_ena : std_logic;
signal env_hold : std_logic;
signal env_inc : std_logic;
signal env_vol : std_logic_vector(4 downto 0);
signal chan_mixed : std_logic_vector(2 downto 0);
signal A : std_logic_vector(4 downto 0);
signal B : std_logic_vector(4 downto 0);
signal C : std_logic_vector(4 downto 0);
type volTableType32 is array (0 to 31) of unsigned(7 downto 0);
type volTableType16 is array (0 to 15) of unsigned(7 downto 0);
constant volTableAy : volTableType16 :=(
x"00", x"03", x"04", x"06",
x"0a", x"0f", x"15", x"22",
x"28", x"41", x"5b", x"72",
x"90", x"b5", x"d7", x"ff"
);
constant volTableYm : volTableType32 :=(
x"00", x"01", x"01", x"02", x"02", x"03", x"03", x"04",
x"06", x"07", x"09", x"0a", x"0c", x"0e", x"11", x"13",
x"17", x"1b", x"20", x"25", x"2c", x"35", x"3e", x"47",
x"54", x"66", x"77", x"88", x"a1", x"c0", x"e0", x"ff"
);
begin
--p_waddr : process(RESET_H, busctrl_addr)
process(clk)
begin
if clk'event and clk = '1' then
if (RESET_H = '1') then
addr <= (others => '0');
elsif busctrl_addr = '1' then -- yuk
addr <= I_DA(4 downto 0);
end if;
end if;
end process;
--p_wdata : process(RESET_H, busctrl_we, addr)
process(clk)
begin
if clk'event and clk = '1' then
env_reset <= '0';
if RESET_H = '1' then
reg <= (others => (others => '0'));
reg(7) <= x"ff";
elsif busctrl_we = '1' and addr(4) = '0' then -- bits 7:5 are checked for 0 outside this module
case addr(3 downto 0) is
when x"0" => reg(0) <= I_DA;
when x"1" => reg(1) <= I_DA;
when x"2" => reg(2) <= I_DA;
when x"3" => reg(3) <= I_DA;
when x"4" => reg(4) <= I_DA;
when x"5" => reg(5) <= I_DA;
when x"6" => reg(6) <= I_DA;
when x"7" => reg(7) <= I_DA;
when x"8" => reg(8) <= I_DA;
when x"9" => reg(9) <= I_DA;
when x"A" => reg(10) <= I_DA;
when x"B" => reg(11) <= I_DA;
when x"C" => reg(12) <= I_DA;
when x"D" => reg(13) <= I_DA;
when x"E" => reg(14) <= I_DA;
when x"F" => reg(15) <= I_DA;
when others => null;
end case;
if addr(3 downto 0) = x"D" then
env_reset <= '1';
end if;
end if;
end if;
end process;
--p_rdata : process(busctrl_re, addr, reg)
process(clk)
begin
if clk'event and clk = '1' then
if I_REG = '1' then
O_DA <= AY_ID & '0' & addr;
elsif addr(4) = '1' and ctrl_aymode = '0' then
O_DA <= x"FF";
else
case addr(3 downto 0) is
when x"0" => O_DA <= reg(0) ;
when x"1" => O_DA <= (reg(1)(7) and not ctrl_aymode) & (reg(1)(6) and not ctrl_aymode) & (reg(1)(5) and not ctrl_aymode) & (reg(1)(4) and not ctrl_aymode) & reg(1)(3 downto 0) ;
when x"2" => O_DA <= reg(2) ;
when x"3" => O_DA <= (reg(3)(7) and not ctrl_aymode) & (reg(3)(6) and not ctrl_aymode) & (reg(3)(5) and not ctrl_aymode) & (reg(3)(4) and not ctrl_aymode) & reg(3)(3 downto 0) ;
when x"4" => O_DA <= reg(4) ;
when x"5" => O_DA <= (reg(5)(7) and not ctrl_aymode) & (reg(5)(6) and not ctrl_aymode) & (reg(5)(5) and not ctrl_aymode) & (reg(5)(4) and not ctrl_aymode) & reg(5)(3 downto 0) ;
when x"6" => O_DA <= (reg(6)(7) and not ctrl_aymode) & (reg(6)(6) and not ctrl_aymode) & (reg(6)(5) and not ctrl_aymode) & reg(6)(4 downto 0) ;
when x"7" => O_DA <= reg(7) ;
when x"8" => O_DA <= (reg(8)(7) and not ctrl_aymode) & (reg(8)(6) and not ctrl_aymode) & (reg(8)(5) and not ctrl_aymode) & reg(8)(4 downto 0) ;
when x"9" => O_DA <= (reg(9)(7) and not ctrl_aymode) & (reg(9)(6) and not ctrl_aymode) & (reg(9)(5) and not ctrl_aymode) & reg(9)(4 downto 0) ;
when x"A" => O_DA <= (reg(10)(7) and not ctrl_aymode) & (reg(10)(6) and not ctrl_aymode) & (reg(10)(5) and not ctrl_aymode) & reg(10)(4 downto 0) ;
when x"B" => O_DA <= reg(11);
when x"C" => O_DA <= reg(12);
when x"D" => O_DA <= (reg(13)(7) and not ctrl_aymode) & (reg(13)(6) and not ctrl_aymode) & (reg(13)(5) and not ctrl_aymode) & (reg(13)(4) and not ctrl_aymode) & reg(13)(3 downto 0) ;
when x"E" => if (reg(7)(6) = '0') then -- input
O_DA <= port_a_i;
else
O_DA <= reg(14) and port_a_i;
end if;
when x"F" => if (Reg(7)(7) = '0') then
O_DA <= port_b_i;
else
O_DA <= reg(15) and port_b_i;
end if;
when others => null;
end case;
end if;
end if;
end process;
port_a_o <= reg(14);
port_b_o <= reg(15);
-- p_divider : process
process(clk)
begin
if clk'event and clk = '1' then
if ENA = '1' then
ena_div <= '0';
ena_div_noise <= '0';
if (cnt_div = "0000") then
cnt_div <= (not I_SEL_L) & "111";
ena_div <= '1';
noise_div <= not noise_div;
if (noise_div = '1') then
ena_div_noise <= '1';
end if;
else
cnt_div <= std_logic_vector(unsigned(cnt_div) - 1);
end if;
end if;
end if;
end process;
-- p_noise_gen : process
noise_gen_comp <= (std_logic_vector(unsigned(reg(6)(4 downto 0)) - 1)) when (reg(6)(4 downto 1) /= "0000") else (others => '0');
poly17_zero <= '1' when (poly17 = "00000000000000000") else '0';
process(clk)
begin
if clk'event and clk = '1' then
if (ENA = '1') then
if (ena_div_noise = '1') then -- divider ena
if (noise_gen_cnt >= noise_gen_comp) then
noise_gen_cnt <= "00000";
poly17 <= (poly17(0) xor poly17(2) xor poly17_zero) & poly17(16 downto 1);
else
noise_gen_cnt <= std_logic_vector(unsigned(noise_gen_cnt) + 1);
end if;
end if;
end if;
end if;
end process;
noise_gen_op <= poly17(0);
--p_tone_gens : process
tone_gen_freq(1) <= reg(1)(3 downto 0) & reg(0);
tone_gen_freq(2) <= reg(3)(3 downto 0) & reg(2);
tone_gen_freq(3) <= reg(5)(3 downto 0) & reg(4);
tone_gen_comp(1) <= (std_logic_vector(unsigned(tone_gen_freq(1)) - 1)) when (tone_gen_freq(1)(11 downto 1) /= (x"00" & "000")) else (others => '0');
tone_gen_comp(2) <= (std_logic_vector(unsigned(tone_gen_freq(2)) - 1)) when (tone_gen_freq(2)(11 downto 1) /= (x"00" & "000")) else (others => '0');
tone_gen_comp(3) <= (std_logic_vector(unsigned(tone_gen_freq(3)) - 1)) when (tone_gen_freq(3)(11 downto 1) /= (x"00" & "000")) else (others => '0');
process(clk)
begin
if clk'event and clk = '1' then
if (ENA = '1') then
for i in 1 to 3 loop
if (ena_div = '1') then -- divider ena
if (tone_gen_cnt(i) >= tone_gen_comp(i)) then
tone_gen_cnt(i) <= x"000";
tone_gen_op(i) <= not tone_gen_op(i);
else
tone_gen_cnt(i) <= std_logic_vector(unsigned(tone_gen_cnt(i)) + 1);
end if;
end if;
end loop;
end if;
end if;
end process;
--p_envelope_freq : process
env_gen_freq <= reg(12) & reg(11);
env_gen_comp <= (std_logic_vector(unsigned(env_gen_freq) - 1)) when (env_gen_freq(15 downto 1) /= (x"000" & "000")) else (others => '0');
process(clk)
begin
if clk'event and clk = '1' then
if env_reset = '1' then
env_gen_cnt <= x"0000";
env_ena <= '1';
elsif (ENA = '1') then
if (ena_div = '1') then -- divider ena
if (env_gen_cnt >= env_gen_comp) then
env_gen_cnt <= x"0000";
env_ena <= '1';
else
env_gen_cnt <= std_logic_vector( unsigned( env_gen_cnt ) + 1 );
env_ena <= '0';
end if;
else
env_ena <= '0';
end if;
end if;
end if;
end process;
--p_envelope_shape : process(env_reset, CLK)
is_zero <= '1' when env_vol(4 downto 1) = "0000" else '0';
is_ones <= '1' when env_vol(4 downto 1) = "1111" else '0';
is_bot <= '1' when is_zero = '1' and env_vol(0) = '0' else '0';
is_bot_p1 <= '1' when is_zero ='1' and env_vol(0) = '1' else '0';
is_top_m1 <= '1' when is_ones = '1' and env_vol(0) = '0' else '0';
is_top <= '1' when is_ones = '1' and env_vol(0) = '1' else '0';
process(clk)
begin
-- envelope shapes
-- C AtAlH
-- 0 0 x x \___
--
-- 0 1 x x /___
--
-- 1 0 0 0 \\\\
--
-- 1 0 0 1 \___
--
-- 1 0 1 0 \/\/
-- ___
-- 1 0 1 1 \
--
-- 1 1 0 0 ////
-- ___
-- 1 1 0 1 /
--
-- 1 1 1 0 /\/\
--
-- 1 1 1 1 /___
if clk'event and clk = '1' then
if env_reset = '1' then
-- load initial state
if (reg(13)(2) = '0') then -- attack
env_vol <= "11111";
env_inc <= '0'; -- -1
else
env_vol <= "00000";
env_inc <= '1'; -- +1
end if;
env_hold <= '0';
elsif (ENA = '1') and (env_ena = '1') then
if (env_hold = '0') then
if (env_inc = '1') then
env_vol <= std_logic_vector( unsigned( env_vol ) + "00001");
else
env_vol <= std_logic_vector( unsigned( env_vol ) + "11111");
end if;
end if;
-- envelope shape control.
if (reg(13)(3) = '0') then
if (env_inc = '0') then -- down
if is_bot_p1 = '1' then
env_hold <= '1';
end if;
else
if is_top = '1' then
env_hold <= '1';
end if;
end if;
elsif (reg(13)(0) = '1') then -- hold = 1
if (env_inc = '0') then -- down
if (reg(13)(1) = '1') then -- alt
if is_bot = '1' then
env_hold <= '1';
end if;
else
if is_bot_p1 = '1' then
env_hold <= '1';
end if;
end if;
else
if (reg(13)(1) = '1') then -- alt
if is_top = '1' then
env_hold <= '1';
end if;
else
if is_top_m1 = '1' then
env_hold <= '1';
end if;
end if;
end if;
elsif (reg(13)(1) = '1') then -- alternate
if (env_inc = '0') then -- down
if is_bot_p1 = '1' then
env_hold <= '1';
end if;
if is_bot = '1' then
env_hold <= '0';
env_inc <= '1';
end if;
else
if is_top_m1 = '1' then
env_hold <= '1';
end if;
if is_top = '1' then
env_hold <= '0';
env_inc <= '0';
end if;
end if;
end if;
end if;
end if;
end process;
--p_chan_mixer_table : process
chan_mixed(0) <= (reg(7)(0) or tone_gen_op(1)) and (reg(7)(3) or noise_gen_op);
chan_mixed(1) <= (reg(7)(1) or tone_gen_op(2)) and (reg(7)(4) or noise_gen_op);
chan_mixed(2) <= (reg(7)(2) or tone_gen_op(3)) and (reg(7)(5) or noise_gen_op);
process(clk)
begin
if clk'event and clk = '1' then
if (ENA = '1') then
A <= "00000";
B <= "00000";
C <= "00000";
if (chan_mixed(0) = '1') then
if (reg(8)(4) = '0') then
if (reg(8)(3 downto 0) = "0000") then
A <= "00000";
else
A <= reg(8)(3 downto 0) & "1";
end if;
else
A <= env_vol(4 downto 0);
end if;
end if;
if (chan_mixed(1) = '1') then
if (reg(9)(4) = '0') then
if (reg(9)(3 downto 0) = "0000") then
B <= "00000";
else
B <= reg(9)(3 downto 0) & "1";
end if;
else
B <= env_vol(4 downto 0);
end if;
end if;
if (chan_mixed(2) = '1') then
if (reg(10)(4) = '0') then
if (reg(10)(3 downto 0) = "0000") then
C <= "00000";
else
C <= reg(10)(3 downto 0) & "1";
end if;
else
C <= env_vol(4 downto 0);
end if;
end if;
end if;
end if;
end process;
process(clk)
begin
if clk'event and clk = '1' then
if RESET_H = '1' then
O_AUDIO_A <= x"00";
O_AUDIO_B <= x"00";
O_AUDIO_C <= x"00";
else
if(ctrl_aymode = '0') then
O_AUDIO_A <= std_logic_vector( volTableYm( to_integer( unsigned( A ) ) ) );
O_AUDIO_B <= std_logic_vector( volTableYm( to_integer( unsigned( B ) ) ) );
O_AUDIO_C <= std_logic_vector( volTableYm( to_integer( unsigned( C ) ) ) );
else
O_AUDIO_A <= std_logic_vector( volTableAy( to_integer( unsigned( A(4 downto 1) ) ) ) );
O_AUDIO_B <= std_logic_vector( volTableAy( to_integer( unsigned( B(4 downto 1) ) ) ) );
O_AUDIO_C <= std_logic_vector( volTableAy( to_integer( unsigned( C(4 downto 1) ) ) ) );
end if;
end if;
end if;
end process;
end architecture RTL;

13
fpga/syn/clocks.sdc Executable file
View File

@ -0,0 +1,13 @@
create_clock -period 28MHz -name {clk28} [get_ports {clk_in}]
# clkcpu 3.5 or 7 MHz
create_generated_clock -name {clkcpu} -divide_by 4 -source [get_ports {clk_in}] [get_registers {cpucontrol:cpucontrol0|clkcpu}]
# hc0[2] 3.5 MHz
create_generated_clock -name {hc0_2} -divide_by 8 -source [get_ports {clk_in}] [get_registers {screen:screen0|hc0[2]}]
# hsync len 4.7uS, 14e6/(1/4.7e-6) ~= 65
create_generated_clock -name {hsync} -divide_by 126 -source [get_ports {clk_in}] [get_registers {screen:screen0|hsync}]
derive_pll_clocks
derive_clocks -period 14MHz

3
fpga/syn/ip/asmi.qip Executable file
View File

@ -0,0 +1,3 @@
set_global_assignment -name IP_TOOL_NAME "ALTASMI_PARALLEL"
set_global_assignment -name IP_TOOL_VERSION "13.0"
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "asmi.v"]

996
fpga/syn/ip/asmi.v Executable file
View File

@ -0,0 +1,996 @@
// megafunction wizard: %ALTASMI_PARALLEL%
// GENERATION: STANDARD
// VERSION: WM1.0
// MODULE: ALTASMI_PARALLEL
// ============================================================
// File Name: asmi.v
// Megafunction Name(s):
// ALTASMI_PARALLEL
//
// Simulation Library Files(s):
//
// ============================================================
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 13.0.1 Build 232 06/12/2013 SP 1 SJ Full Version
// ************************************************************
//Copyright (C) 1991-2013 Altera Corporation
//Your use of Altera Corporation's design tools, logic functions
//and other software and tools, and its AMPP partner logic
//functions, and any output files from any of the foregoing
//(including device programming or simulation files), and any
//associated documentation or information are expressly subject
//to the terms and conditions of the Altera Program License
//Subscription Agreement, Altera MegaCore Function License
//Agreement, or other applicable license agreement, including,
//without limitation, that your use is for the sole purpose of
//programming logic devices manufactured by Altera and sold by
//Altera or its authorized distributors. Please refer to the
//applicable agreement for further details.
//altasmi_parallel CBX_AUTO_BLACKBOX="ALL" DATA_WIDTH="STANDARD" DEVICE_FAMILY="Cyclone" EPCS_TYPE="EPCS4" PAGE_SIZE=1 PORT_BULK_ERASE="PORT_UNUSED" PORT_DIE_ERASE="PORT_UNUSED" PORT_EN4B_ADDR="PORT_UNUSED" PORT_FAST_READ="PORT_UNUSED" PORT_ILLEGAL_ERASE="PORT_UNUSED" PORT_ILLEGAL_WRITE="PORT_UNUSED" PORT_RDID_OUT="PORT_UNUSED" PORT_READ_ADDRESS="PORT_UNUSED" PORT_READ_DUMMYCLK="PORT_UNUSED" PORT_READ_RDID="PORT_UNUSED" PORT_READ_SID="PORT_UNUSED" PORT_READ_STATUS="PORT_UNUSED" PORT_SECTOR_ERASE="PORT_UNUSED" PORT_SECTOR_PROTECT="PORT_UNUSED" PORT_SHIFT_BYTES="PORT_UNUSED" PORT_WREN="PORT_UNUSED" PORT_WRITE="PORT_UNUSED" USE_ASMIBLOCK="ON" USE_EAB="ON" WRITE_DUMMY_CLK=0 addr busy clkin data_valid dataout rden read reset INTENDED_DEVICE_FAMILY="Cyclone" ALTERA_INTERNAL_OPTIONS=SUPPRESS_DA_RULE_INTERNAL=C106
//VERSION_BEGIN 13.0 cbx_a_gray2bin 2013:06:12:18:03:43:SJ cbx_a_graycounter 2013:06:12:18:03:43:SJ cbx_altasmi_parallel 2013:06:12:18:03:43:SJ cbx_altdpram 2013:06:12:18:03:43:SJ cbx_altsyncram 2013:06:12:18:03:43:SJ cbx_arriav 2013:06:12:18:03:43:SJ cbx_cyclone 2013:06:12:18:03:43:SJ cbx_cycloneii 2013:06:12:18:03:43:SJ cbx_fifo_common 2013:06:12:18:03:43:SJ cbx_lpm_add_sub 2013:06:12:18:03:43:SJ cbx_lpm_compare 2013:06:12:18:03:43:SJ cbx_lpm_counter 2013:06:12:18:03:43:SJ cbx_lpm_decode 2013:06:12:18:03:43:SJ cbx_lpm_mux 2013:06:12:18:03:43:SJ cbx_mgl 2013:06:12:18:05:10:SJ cbx_scfifo 2013:06:12:18:03:43:SJ cbx_stratix 2013:06:12:18:03:43:SJ cbx_stratixii 2013:06:12:18:03:43:SJ cbx_stratixiii 2013:06:12:18:03:43:SJ cbx_stratixv 2013:06:12:18:03:43:SJ cbx_util_mgl 2013:06:12:18:03:43:SJ VERSION_END
// synthesis VERILOG_INPUT_VERSION VERILOG_2001
// altera message_off 10463
//synthesis_resources = a_graycounter 3 cyclone_asmiblock 1 lut 74 mux21 1
//synopsys translate_off
`timescale 1 ps / 1 ps
//synopsys translate_on
(* ALTERA_ATTRIBUTE = {"SUPPRESS_DA_RULE_INTERNAL=C106"} *)
module asmi_altasmi_parallel_gqd2
(
addr,
busy,
clkin,
data_valid,
dataout,
rden,
read,
reset) /* synthesis synthesis_clearbox=2 */;
input [23:0] addr;
output busy;
input clkin;
output data_valid;
output [7:0] dataout;
input rden;
input read;
input reset;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_off
`endif
tri0 read;
tri0 reset;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_on
`endif
wire [2:0] wire_addbyte_cntr_q;
wire [2:0] wire_gen_cntr_q;
wire [1:0] wire_stage_cntr_q;
wire wire_cyclone_asmiblock2_data0out;
reg add_msb_reg;
wire wire_add_msb_reg_ena;
wire [23:0] wire_addr_reg_d;
reg [23:0] addr_reg;
wire [23:0] wire_addr_reg_ena;
wire [7:0] wire_asmi_opcode_reg_d;
reg [7:0] asmi_opcode_reg;
wire [7:0] wire_asmi_opcode_reg_ena;
reg busy_det_reg;
reg clr_read_reg;
reg clr_read_reg2;
reg dffe3;
reg dvalid_reg;
wire wire_dvalid_reg_ena;
wire wire_dvalid_reg_sclr;
reg dvalid_reg2;
reg end1_cyc_reg;
reg end1_cyc_reg2;
reg end_op_hdlyreg;
reg end_op_reg;
reg end_rbyte_reg;
wire wire_end_rbyte_reg_ena;
wire wire_end_rbyte_reg_sclr;
reg end_read_reg;
reg ncs_reg;
wire wire_ncs_reg_ena;
wire wire_ncs_reg_sclr;
wire [7:0] wire_read_data_reg_d;
reg [7:0] read_data_reg;
wire [7:0] wire_read_data_reg_ena;
wire [7:0] wire_read_dout_reg_d;
reg [7:0] read_dout_reg;
wire [7:0] wire_read_dout_reg_ena;
reg read_reg;
wire wire_read_reg_ena;
reg shift_op_reg;
reg stage2_reg;
reg stage3_reg;
reg stage4_reg;
wire wire_mux211_dataout;
wire addr_overdie;
wire addr_overdie_pos;
wire [23:0] addr_reg_overdie;
wire [7:0] b4addr_opcode;
wire [7:0] berase_opcode;
wire busy_wire;
wire clkin_wire;
wire clr_addmsb_wire;
wire clr_endrbyte_wire;
wire clr_read_wire;
wire clr_read_wire2;
wire clr_write_wire2;
wire data0out_wire;
wire data_valid_wire;
wire [3:0] datain_wire;
wire [3:0] dataout_wire;
wire [7:0] derase_opcode;
wire do_4baddr;
wire do_bulk_erase;
wire do_die_erase;
wire do_fast_read;
wire do_fread_epcq;
wire do_freadwrv_polling;
wire do_memadd;
wire do_polling;
wire do_read;
wire do_read_nonvolatile;
wire do_read_rdid;
wire do_read_sid;
wire do_read_stat;
wire do_read_volatile;
wire do_sec_erase;
wire do_sec_prot;
wire do_sprot_polling;
wire do_wait_dummyclk;
wire do_wren;
wire do_write;
wire do_write_polling;
wire do_write_volatile;
wire end1_cyc_gen_cntr_wire;
wire end1_cyc_normal_in_wire;
wire end1_cyc_reg_in_wire;
wire end_add_cycle;
wire end_add_cycle_mux_datab_wire;
wire end_fast_read;
wire end_one_cyc_pos;
wire end_one_cycle;
wire end_op_wire;
wire end_operation;
wire end_ophdly;
wire end_pgwr_data;
wire end_read;
wire end_read_byte;
wire [7:0] fast_read_opcode;
wire freadwrv_sdoin;
wire in_operation;
wire load_opcode;
wire memadd_sdoin;
wire not_busy;
wire oe_wire;
wire [0:0] pagewr_buf_not_empty;
wire rden_wire;
wire [7:0] rdid_opcode;
wire [7:0] rdummyclk_opcode;
wire [7:0] read_data_reg_in_wire;
wire [7:0] read_opcode;
wire read_rdid_wire;
wire read_sid_wire;
wire read_wire;
wire [7:0] rflagstat_opcode;
wire [7:0] rnvdummyclk_opcode;
wire [7:0] rsid_opcode;
wire rsid_sdoin;
wire [7:0] rstat_opcode;
wire scein_wire;
wire sdoin_wire;
wire sec_protect_wire;
wire [7:0] secprot_opcode;
wire secprot_sdoin;
wire [7:0] serase_opcode;
wire shift_opcode;
wire shift_opdata;
wire shift_pgwr_data;
wire st_busy_wire;
wire stage2_wire;
wire stage3_wire;
wire stage4_wire;
wire start_frpoll;
wire start_poll;
wire start_sppoll;
wire start_wrpoll;
wire to_sdoin_wire;
wire [7:0] wren_opcode;
wire wren_wire;
wire [7:0] write_opcode;
wire write_prot_true;
wire write_sdoin;
wire [7:0] wrvolatile_opcode;
a_graycounter addbyte_cntr
(
.aclr(reset),
.clk_en((((((wire_stage_cntr_q[1] & wire_stage_cntr_q[0]) & end_one_cyc_pos) & (((((((do_read_sid | do_write) | do_sec_erase) | do_die_erase) | do_read_rdid) | do_read) | do_fast_read) | do_read_nonvolatile)) | addr_overdie) | end_operation)),
.clock((~ clkin_wire)),
.q(wire_addbyte_cntr_q),
.qbin(),
.sclr((end_operation | addr_overdie))
`ifndef FORMAL_VERIFICATION
// synopsys translate_off
`endif
,
.cnt_en(1'b1),
.updown(1'b1)
`ifndef FORMAL_VERIFICATION
// synopsys translate_on
`endif
);
defparam
addbyte_cntr.width = 3,
addbyte_cntr.lpm_type = "a_graycounter";
a_graycounter gen_cntr
(
.aclr(reset),
.clk_en((((in_operation & (~ end_ophdly)) | do_wait_dummyclk) | addr_overdie)),
.clock(clkin_wire),
.q(wire_gen_cntr_q),
.qbin(),
.sclr(((end1_cyc_reg_in_wire | addr_overdie) | do_wait_dummyclk))
`ifndef FORMAL_VERIFICATION
// synopsys translate_off
`endif
,
.cnt_en(1'b1),
.updown(1'b1)
`ifndef FORMAL_VERIFICATION
// synopsys translate_on
`endif
);
defparam
gen_cntr.width = 3,
gen_cntr.lpm_type = "a_graycounter";
a_graycounter stage_cntr
(
.aclr(reset),
.clk_en(((((((((((((((in_operation & end_one_cycle) & (~ (stage3_wire & (~ end_add_cycle)))) & (~ (stage4_wire & (~ end_read)))) & (~ (stage4_wire & (~ end_fast_read)))) & (~ ((((do_write | do_sec_erase) | do_die_erase) | do_bulk_erase) & write_prot_true))) & (~ (do_write & (~ pagewr_buf_not_empty[0])))) & (~ (stage3_wire & st_busy_wire))) & (~ ((do_write & shift_pgwr_data) & (~ end_pgwr_data)))) & (~ (stage2_wire & do_wren))) & (~ ((((stage3_wire & (do_sec_erase | do_die_erase)) & (~ do_wren)) & (~ do_read_stat)) & (~ do_read_rdid)))) & (~ (stage3_wire & ((do_write_volatile | do_read_volatile) | do_read_nonvolatile)))) | ((stage3_wire & do_fast_read) & do_wait_dummyclk)) | addr_overdie) | end_ophdly)),
.clock(clkin_wire),
.q(wire_stage_cntr_q),
.qbin(),
.sclr((end_operation | addr_overdie))
`ifndef FORMAL_VERIFICATION
// synopsys translate_off
`endif
,
.cnt_en(1'b1),
.updown(1'b1)
`ifndef FORMAL_VERIFICATION
// synopsys translate_on
`endif
);
defparam
stage_cntr.width = 2,
stage_cntr.lpm_type = "a_graycounter";
cyclone_asmiblock cyclone_asmiblock2
(
.data0out(wire_cyclone_asmiblock2_data0out),
.dclkin(clkin_wire),
.oe(oe_wire),
.scein(scein_wire),
.sdoin((sdoin_wire | datain_wire[0])));
// synopsys translate_off
initial
add_msb_reg = 0;
// synopsys translate_on
always @ ( negedge clkin_wire or posedge reset)
if (reset == 1'b1) add_msb_reg <= 1'b0;
else if (wire_add_msb_reg_ena == 1'b1)
if (clr_addmsb_wire == 1'b1) add_msb_reg <= 1'b0;
else add_msb_reg <= addr_reg[23];
assign
wire_add_msb_reg_ena = ((((((((do_read | do_fast_read) | do_write) | do_sec_erase) | do_die_erase) & (~ (((do_write | do_sec_erase) | do_die_erase) & (~ do_memadd)))) & wire_stage_cntr_q[1]) & wire_stage_cntr_q[0]) | clr_addmsb_wire);
// synopsys translate_off
initial
addr_reg[0:0] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) addr_reg[0:0] <= 1'b0;
else if (wire_addr_reg_ena[0:0] == 1'b1) addr_reg[0:0] <= wire_addr_reg_d[0:0];
// synopsys translate_off
initial
addr_reg[1:1] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) addr_reg[1:1] <= 1'b0;
else if (wire_addr_reg_ena[1:1] == 1'b1) addr_reg[1:1] <= wire_addr_reg_d[1:1];
// synopsys translate_off
initial
addr_reg[2:2] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) addr_reg[2:2] <= 1'b0;
else if (wire_addr_reg_ena[2:2] == 1'b1) addr_reg[2:2] <= wire_addr_reg_d[2:2];
// synopsys translate_off
initial
addr_reg[3:3] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) addr_reg[3:3] <= 1'b0;
else if (wire_addr_reg_ena[3:3] == 1'b1) addr_reg[3:3] <= wire_addr_reg_d[3:3];
// synopsys translate_off
initial
addr_reg[4:4] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) addr_reg[4:4] <= 1'b0;
else if (wire_addr_reg_ena[4:4] == 1'b1) addr_reg[4:4] <= wire_addr_reg_d[4:4];
// synopsys translate_off
initial
addr_reg[5:5] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) addr_reg[5:5] <= 1'b0;
else if (wire_addr_reg_ena[5:5] == 1'b1) addr_reg[5:5] <= wire_addr_reg_d[5:5];
// synopsys translate_off
initial
addr_reg[6:6] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) addr_reg[6:6] <= 1'b0;
else if (wire_addr_reg_ena[6:6] == 1'b1) addr_reg[6:6] <= wire_addr_reg_d[6:6];
// synopsys translate_off
initial
addr_reg[7:7] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) addr_reg[7:7] <= 1'b0;
else if (wire_addr_reg_ena[7:7] == 1'b1) addr_reg[7:7] <= wire_addr_reg_d[7:7];
// synopsys translate_off
initial
addr_reg[8:8] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) addr_reg[8:8] <= 1'b0;
else if (wire_addr_reg_ena[8:8] == 1'b1) addr_reg[8:8] <= wire_addr_reg_d[8:8];
// synopsys translate_off
initial
addr_reg[9:9] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) addr_reg[9:9] <= 1'b0;
else if (wire_addr_reg_ena[9:9] == 1'b1) addr_reg[9:9] <= wire_addr_reg_d[9:9];
// synopsys translate_off
initial
addr_reg[10:10] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) addr_reg[10:10] <= 1'b0;
else if (wire_addr_reg_ena[10:10] == 1'b1) addr_reg[10:10] <= wire_addr_reg_d[10:10];
// synopsys translate_off
initial
addr_reg[11:11] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) addr_reg[11:11] <= 1'b0;
else if (wire_addr_reg_ena[11:11] == 1'b1) addr_reg[11:11] <= wire_addr_reg_d[11:11];
// synopsys translate_off
initial
addr_reg[12:12] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) addr_reg[12:12] <= 1'b0;
else if (wire_addr_reg_ena[12:12] == 1'b1) addr_reg[12:12] <= wire_addr_reg_d[12:12];
// synopsys translate_off
initial
addr_reg[13:13] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) addr_reg[13:13] <= 1'b0;
else if (wire_addr_reg_ena[13:13] == 1'b1) addr_reg[13:13] <= wire_addr_reg_d[13:13];
// synopsys translate_off
initial
addr_reg[14:14] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) addr_reg[14:14] <= 1'b0;
else if (wire_addr_reg_ena[14:14] == 1'b1) addr_reg[14:14] <= wire_addr_reg_d[14:14];
// synopsys translate_off
initial
addr_reg[15:15] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) addr_reg[15:15] <= 1'b0;
else if (wire_addr_reg_ena[15:15] == 1'b1) addr_reg[15:15] <= wire_addr_reg_d[15:15];
// synopsys translate_off
initial
addr_reg[16:16] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) addr_reg[16:16] <= 1'b0;
else if (wire_addr_reg_ena[16:16] == 1'b1) addr_reg[16:16] <= wire_addr_reg_d[16:16];
// synopsys translate_off
initial
addr_reg[17:17] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) addr_reg[17:17] <= 1'b0;
else if (wire_addr_reg_ena[17:17] == 1'b1) addr_reg[17:17] <= wire_addr_reg_d[17:17];
// synopsys translate_off
initial
addr_reg[18:18] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) addr_reg[18:18] <= 1'b0;
else if (wire_addr_reg_ena[18:18] == 1'b1) addr_reg[18:18] <= wire_addr_reg_d[18:18];
// synopsys translate_off
initial
addr_reg[19:19] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) addr_reg[19:19] <= 1'b0;
else if (wire_addr_reg_ena[19:19] == 1'b1) addr_reg[19:19] <= wire_addr_reg_d[19:19];
// synopsys translate_off
initial
addr_reg[20:20] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) addr_reg[20:20] <= 1'b0;
else if (wire_addr_reg_ena[20:20] == 1'b1) addr_reg[20:20] <= wire_addr_reg_d[20:20];
// synopsys translate_off
initial
addr_reg[21:21] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) addr_reg[21:21] <= 1'b0;
else if (wire_addr_reg_ena[21:21] == 1'b1) addr_reg[21:21] <= wire_addr_reg_d[21:21];
// synopsys translate_off
initial
addr_reg[22:22] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) addr_reg[22:22] <= 1'b0;
else if (wire_addr_reg_ena[22:22] == 1'b1) addr_reg[22:22] <= wire_addr_reg_d[22:22];
// synopsys translate_off
initial
addr_reg[23:23] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) addr_reg[23:23] <= 1'b0;
else if (wire_addr_reg_ena[23:23] == 1'b1) addr_reg[23:23] <= wire_addr_reg_d[23:23];
assign
wire_addr_reg_d = {((({23{not_busy}} & addr[23:1]) | ({23{stage3_wire}} & addr_reg[22:0])) | ({23{addr_overdie}} & addr_reg_overdie[23:1])), ((not_busy & addr[0]) | (addr_overdie & addr_reg_overdie[0]))};
assign
wire_addr_reg_ena = {24{((((rden_wire | wren_wire) & not_busy) | (stage4_wire & addr_overdie)) | (stage3_wire & ((((do_write | do_sec_erase) | do_die_erase) & do_memadd) | (do_read | do_fast_read))))}};
// synopsys translate_off
initial
asmi_opcode_reg[0:0] = 0;
// synopsys translate_on
always @ ( negedge clkin_wire or posedge reset)
if (reset == 1'b1) asmi_opcode_reg[0:0] <= 1'b0;
else if (wire_asmi_opcode_reg_ena[0:0] == 1'b1) asmi_opcode_reg[0:0] <= wire_asmi_opcode_reg_d[0:0];
// synopsys translate_off
initial
asmi_opcode_reg[1:1] = 0;
// synopsys translate_on
always @ ( negedge clkin_wire or posedge reset)
if (reset == 1'b1) asmi_opcode_reg[1:1] <= 1'b0;
else if (wire_asmi_opcode_reg_ena[1:1] == 1'b1) asmi_opcode_reg[1:1] <= wire_asmi_opcode_reg_d[1:1];
// synopsys translate_off
initial
asmi_opcode_reg[2:2] = 0;
// synopsys translate_on
always @ ( negedge clkin_wire or posedge reset)
if (reset == 1'b1) asmi_opcode_reg[2:2] <= 1'b0;
else if (wire_asmi_opcode_reg_ena[2:2] == 1'b1) asmi_opcode_reg[2:2] <= wire_asmi_opcode_reg_d[2:2];
// synopsys translate_off
initial
asmi_opcode_reg[3:3] = 0;
// synopsys translate_on
always @ ( negedge clkin_wire or posedge reset)
if (reset == 1'b1) asmi_opcode_reg[3:3] <= 1'b0;
else if (wire_asmi_opcode_reg_ena[3:3] == 1'b1) asmi_opcode_reg[3:3] <= wire_asmi_opcode_reg_d[3:3];
// synopsys translate_off
initial
asmi_opcode_reg[4:4] = 0;
// synopsys translate_on
always @ ( negedge clkin_wire or posedge reset)
if (reset == 1'b1) asmi_opcode_reg[4:4] <= 1'b0;
else if (wire_asmi_opcode_reg_ena[4:4] == 1'b1) asmi_opcode_reg[4:4] <= wire_asmi_opcode_reg_d[4:4];
// synopsys translate_off
initial
asmi_opcode_reg[5:5] = 0;
// synopsys translate_on
always @ ( negedge clkin_wire or posedge reset)
if (reset == 1'b1) asmi_opcode_reg[5:5] <= 1'b0;
else if (wire_asmi_opcode_reg_ena[5:5] == 1'b1) asmi_opcode_reg[5:5] <= wire_asmi_opcode_reg_d[5:5];
// synopsys translate_off
initial
asmi_opcode_reg[6:6] = 0;
// synopsys translate_on
always @ ( negedge clkin_wire or posedge reset)
if (reset == 1'b1) asmi_opcode_reg[6:6] <= 1'b0;
else if (wire_asmi_opcode_reg_ena[6:6] == 1'b1) asmi_opcode_reg[6:6] <= wire_asmi_opcode_reg_d[6:6];
// synopsys translate_off
initial
asmi_opcode_reg[7:7] = 0;
// synopsys translate_on
always @ ( negedge clkin_wire or posedge reset)
if (reset == 1'b1) asmi_opcode_reg[7:7] <= 1'b0;
else if (wire_asmi_opcode_reg_ena[7:7] == 1'b1) asmi_opcode_reg[7:7] <= wire_asmi_opcode_reg_d[7:7];
assign
wire_asmi_opcode_reg_d = {((((((((((((((((({7{(load_opcode & do_read_sid)}} & rsid_opcode[7:1]) | ({7{(load_opcode & do_read_rdid)}} & rdid_opcode[7:1])) | ({7{(((load_opcode & do_sec_prot) & (~ do_wren)) & (~ do_read_stat))}} & secprot_opcode[7:1])) | ({7{(load_opcode & do_read)}} & read_opcode[7:1])) | ({7{(load_opcode & do_fast_read)}} & fast_read_opcode[7:1])) | ({7{((((load_opcode & do_read_volatile) & (~ do_write_volatile)) & (~ do_wren)) & (~ do_read_stat))}} & rdummyclk_opcode[7:1])) | ({7{((((load_opcode & do_write_volatile) & (~ do_read_volatile)) & (~ do_wren)) & (~ do_read_stat))}} & wrvolatile_opcode[7:1])) | ({7{(load_opcode & do_read_nonvolatile)}} & rnvdummyclk_opcode[7:1])) | ({7{(load_opcode & ((do_write & (~ do_read_stat)) & (~ do_wren)))}} & write_opcode[7:1])) | ({7{((load_opcode & do_read_stat) & (~ do_polling))}} & rstat_opcode[7:1])) | ({7{((load_opcode & do_read_stat) & do_polling)}} & rflagstat_opcode[7:1])) | ({7{(((load_opcode & do_sec_erase) & (~ do_wren)) & (~ do_read_stat))}} & serase_opcode[7:1])) | ({7{(((load_opcode & do_die_erase) & (~ do_wren)) & (~ do_read_stat))}} & derase_opcode[7:1])) | ({7{(((load_opcode & do_bulk_erase) & (~ do_wren)) & (~ do_read_stat))}} & berase_opcode[7:1])) | ({7{(load_opcode & do_wren)}} & wren_opcode[7:1])) | ({7{(load_opcode & ((do_4baddr & (~ do_read_stat)) & (~ do_wren)))}} & b4addr_opcode[7:1])) | ({7{shift_opcode}} & asmi_opcode_reg[6:0])), (((((((((((((((((load_opcode & do_read_sid) & rsid_opcode[0]) | ((load_opcode & do_read_rdid) & rdid_opcode[0])) | ((((load_opcode & do_sec_prot) & (~ do_wren)) & (~ do_read_stat)) & secprot_opcode[0])) | ((load_opcode & do_read) & read_opcode[0])) | ((load_opcode & do_fast_read) & fast_read_opcode[0])) | (((((load_opcode & do_read_volatile) & (~ do_write_volatile)) & (~ do_wren)) & (~ do_read_stat)) & rdummyclk_opcode[0])) | (((((load_opcode & do_write_volatile) & (~ do_read_volatile)) & (~ do_wren)) & (~ do_read_stat)) & wrvolatile_opcode[0])) | ((load_opcode & do_read_nonvolatile) & rnvdummyclk_opcode[0]
)) | ((load_opcode & ((do_write & (~ do_read_stat)) & (~ do_wren))) & write_opcode[0])) | (((load_opcode & do_read_stat) & (~ do_polling)) & rstat_opcode[0])) | (((load_opcode & do_read_stat) & do_polling) & rflagstat_opcode[0])) | ((((load_opcode & do_sec_erase) & (~ do_wren)) & (~ do_read_stat)) & serase_opcode[0])) | ((((load_opcode & do_die_erase) & (~ do_wren)) & (~ do_read_stat)) & derase_opcode[0])) | ((((load_opcode & do_bulk_erase) & (~ do_wren)) & (~ do_read_stat)) & berase_opcode[0])) | ((load_opcode & do_wren) & wren_opcode[0])) | ((load_opcode & ((do_4baddr & (~ do_read_stat)) & (~ do_wren))) & b4addr_opcode[0]))};
assign
wire_asmi_opcode_reg_ena = {8{(load_opcode | shift_opcode)}};
// synopsys translate_off
initial
busy_det_reg = 0;
// synopsys translate_on
always @ ( negedge clkin_wire or posedge reset)
if (reset == 1'b1) busy_det_reg <= 1'b0;
else busy_det_reg <= (~ busy_wire);
// synopsys translate_off
initial
clr_read_reg = 0;
// synopsys translate_on
always @ ( negedge clkin_wire or posedge reset)
if (reset == 1'b1) clr_read_reg <= 1'b0;
else clr_read_reg <= ((do_read_sid | do_sec_prot) | end_operation);
// synopsys translate_off
initial
clr_read_reg2 = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) clr_read_reg2 <= 1'b0;
else clr_read_reg2 <= clr_read_reg;
// synopsys translate_off
initial
dffe3 = 0;
// synopsys translate_on
// synopsys translate_off
initial
dvalid_reg = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) dvalid_reg <= 1'b0;
else if (wire_dvalid_reg_ena == 1'b1)
if (wire_dvalid_reg_sclr == 1'b1) dvalid_reg <= 1'b0;
else dvalid_reg <= (end_read_byte & end_one_cyc_pos);
assign
wire_dvalid_reg_ena = (do_read | do_fast_read),
wire_dvalid_reg_sclr = (end_op_wire | end_operation);
// synopsys translate_off
initial
dvalid_reg2 = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) dvalid_reg2 <= 1'b0;
else dvalid_reg2 <= dvalid_reg;
// synopsys translate_off
initial
end1_cyc_reg = 0;
// synopsys translate_on
always @ ( negedge clkin_wire or posedge reset)
if (reset == 1'b1) end1_cyc_reg <= 1'b0;
else end1_cyc_reg <= end1_cyc_reg_in_wire;
// synopsys translate_off
initial
end1_cyc_reg2 = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) end1_cyc_reg2 <= 1'b0;
else end1_cyc_reg2 <= end_one_cycle;
// synopsys translate_off
initial
end_op_hdlyreg = 0;
// synopsys translate_on
always @ ( negedge clkin_wire or posedge reset)
if (reset == 1'b1) end_op_hdlyreg <= 1'b0;
else end_op_hdlyreg <= end_operation;
// synopsys translate_off
initial
end_op_reg = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) end_op_reg <= 1'b0;
else end_op_reg <= end_op_wire;
// synopsys translate_off
initial
end_rbyte_reg = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) end_rbyte_reg <= 1'b0;
else if (wire_end_rbyte_reg_ena == 1'b1)
if (wire_end_rbyte_reg_sclr == 1'b1) end_rbyte_reg <= 1'b0;
else end_rbyte_reg <= (((do_read | do_fast_read) & wire_stage_cntr_q[1]) & (~ wire_stage_cntr_q[0]));
assign
wire_end_rbyte_reg_ena = (((wire_gen_cntr_q[2] & (~ wire_gen_cntr_q[1])) & wire_gen_cntr_q[0]) | clr_endrbyte_wire),
wire_end_rbyte_reg_sclr = (clr_endrbyte_wire | addr_overdie);
// synopsys translate_off
initial
end_read_reg = 0;
// synopsys translate_on
always @ ( negedge clkin_wire or posedge reset)
if (reset == 1'b1) end_read_reg <= 1'b0;
else end_read_reg <= ((((~ rden_wire) & (do_read | do_fast_read)) & data_valid_wire) & end_read_byte);
// synopsys translate_off
initial
ncs_reg = 0;
// synopsys translate_on
always @ ( negedge clkin_wire or posedge reset)
if (reset == 1'b1) ncs_reg <= 1'b0;
else if (wire_ncs_reg_ena == 1'b1)
if (wire_ncs_reg_sclr == 1'b1) ncs_reg <= 1'b0;
else ncs_reg <= 1'b1;
assign
wire_ncs_reg_ena = (((((~ wire_stage_cntr_q[1]) & wire_stage_cntr_q[0]) & end_one_cyc_pos) | addr_overdie_pos) | end_operation),
wire_ncs_reg_sclr = (end_operation | addr_overdie_pos);
// synopsys translate_off
initial
read_data_reg[0:0] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) read_data_reg[0:0] <= 1'b0;
else if (wire_read_data_reg_ena[0:0] == 1'b1) read_data_reg[0:0] <= wire_read_data_reg_d[0:0];
// synopsys translate_off
initial
read_data_reg[1:1] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) read_data_reg[1:1] <= 1'b0;
else if (wire_read_data_reg_ena[1:1] == 1'b1) read_data_reg[1:1] <= wire_read_data_reg_d[1:1];
// synopsys translate_off
initial
read_data_reg[2:2] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) read_data_reg[2:2] <= 1'b0;
else if (wire_read_data_reg_ena[2:2] == 1'b1) read_data_reg[2:2] <= wire_read_data_reg_d[2:2];
// synopsys translate_off
initial
read_data_reg[3:3] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) read_data_reg[3:3] <= 1'b0;
else if (wire_read_data_reg_ena[3:3] == 1'b1) read_data_reg[3:3] <= wire_read_data_reg_d[3:3];
// synopsys translate_off
initial
read_data_reg[4:4] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) read_data_reg[4:4] <= 1'b0;
else if (wire_read_data_reg_ena[4:4] == 1'b1) read_data_reg[4:4] <= wire_read_data_reg_d[4:4];
// synopsys translate_off
initial
read_data_reg[5:5] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) read_data_reg[5:5] <= 1'b0;
else if (wire_read_data_reg_ena[5:5] == 1'b1) read_data_reg[5:5] <= wire_read_data_reg_d[5:5];
// synopsys translate_off
initial
read_data_reg[6:6] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) read_data_reg[6:6] <= 1'b0;
else if (wire_read_data_reg_ena[6:6] == 1'b1) read_data_reg[6:6] <= wire_read_data_reg_d[6:6];
// synopsys translate_off
initial
read_data_reg[7:7] = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) read_data_reg[7:7] <= 1'b0;
else if (wire_read_data_reg_ena[7:7] == 1'b1) read_data_reg[7:7] <= wire_read_data_reg_d[7:7];
assign
wire_read_data_reg_d = {read_data_reg_in_wire[7:0]};
assign
wire_read_data_reg_ena = {8{(((((do_read | do_fast_read) & wire_stage_cntr_q[1]) & (~ wire_stage_cntr_q[0])) & end_one_cyc_pos) & end_read_byte)}};
// synopsys translate_off
initial
read_dout_reg[0:0] = 0;
// synopsys translate_on
always @ ( negedge clkin_wire or posedge reset)
if (reset == 1'b1) read_dout_reg[0:0] <= 1'b0;
else if (wire_read_dout_reg_ena[0:0] == 1'b1) read_dout_reg[0:0] <= wire_read_dout_reg_d[0:0];
// synopsys translate_off
initial
read_dout_reg[1:1] = 0;
// synopsys translate_on
always @ ( negedge clkin_wire or posedge reset)
if (reset == 1'b1) read_dout_reg[1:1] <= 1'b0;
else if (wire_read_dout_reg_ena[1:1] == 1'b1) read_dout_reg[1:1] <= wire_read_dout_reg_d[1:1];
// synopsys translate_off
initial
read_dout_reg[2:2] = 0;
// synopsys translate_on
always @ ( negedge clkin_wire or posedge reset)
if (reset == 1'b1) read_dout_reg[2:2] <= 1'b0;
else if (wire_read_dout_reg_ena[2:2] == 1'b1) read_dout_reg[2:2] <= wire_read_dout_reg_d[2:2];
// synopsys translate_off
initial
read_dout_reg[3:3] = 0;
// synopsys translate_on
always @ ( negedge clkin_wire or posedge reset)
if (reset == 1'b1) read_dout_reg[3:3] <= 1'b0;
else if (wire_read_dout_reg_ena[3:3] == 1'b1) read_dout_reg[3:3] <= wire_read_dout_reg_d[3:3];
// synopsys translate_off
initial
read_dout_reg[4:4] = 0;
// synopsys translate_on
always @ ( negedge clkin_wire or posedge reset)
if (reset == 1'b1) read_dout_reg[4:4] <= 1'b0;
else if (wire_read_dout_reg_ena[4:4] == 1'b1) read_dout_reg[4:4] <= wire_read_dout_reg_d[4:4];
// synopsys translate_off
initial
read_dout_reg[5:5] = 0;
// synopsys translate_on
always @ ( negedge clkin_wire or posedge reset)
if (reset == 1'b1) read_dout_reg[5:5] <= 1'b0;
else if (wire_read_dout_reg_ena[5:5] == 1'b1) read_dout_reg[5:5] <= wire_read_dout_reg_d[5:5];
// synopsys translate_off
initial
read_dout_reg[6:6] = 0;
// synopsys translate_on
always @ ( negedge clkin_wire or posedge reset)
if (reset == 1'b1) read_dout_reg[6:6] <= 1'b0;
else if (wire_read_dout_reg_ena[6:6] == 1'b1) read_dout_reg[6:6] <= wire_read_dout_reg_d[6:6];
// synopsys translate_off
initial
read_dout_reg[7:7] = 0;
// synopsys translate_on
always @ ( negedge clkin_wire or posedge reset)
if (reset == 1'b1) read_dout_reg[7:7] <= 1'b0;
else if (wire_read_dout_reg_ena[7:7] == 1'b1) read_dout_reg[7:7] <= wire_read_dout_reg_d[7:7];
assign
wire_read_dout_reg_d = {read_dout_reg[6:0], (data0out_wire | dataout_wire[1])};
assign
wire_read_dout_reg_ena = {8{((stage4_wire & ((do_read | do_fast_read) | do_read_sid)) | (stage3_wire & (((do_read_stat | do_read_rdid) | do_read_volatile) | do_read_nonvolatile)))}};
// synopsys translate_off
initial
read_reg = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) read_reg <= 1'b0;
else if (wire_read_reg_ena == 1'b1)
if (clr_read_wire == 1'b1) read_reg <= 1'b0;
else read_reg <= read;
assign
wire_read_reg_ena = (((~ busy_wire) & rden_wire) | clr_read_wire);
// synopsys translate_off
initial
shift_op_reg = 0;
// synopsys translate_on
always @ ( posedge clkin_wire or posedge reset)
if (reset == 1'b1) shift_op_reg <= 1'b0;
else shift_op_reg <= ((~ wire_stage_cntr_q[1]) & wire_stage_cntr_q[0]);
// synopsys translate_off
initial
stage2_reg = 0;
// synopsys translate_on
always @ ( negedge clkin_wire or posedge reset)
if (reset == 1'b1) stage2_reg <= 1'b0;
else stage2_reg <= ((~ wire_stage_cntr_q[1]) & wire_stage_cntr_q[0]);
// synopsys translate_off
initial
stage3_reg = 0;
// synopsys translate_on
always @ ( negedge clkin_wire or posedge reset)
if (reset == 1'b1) stage3_reg <= 1'b0;
else stage3_reg <= (wire_stage_cntr_q[1] & wire_stage_cntr_q[0]);
// synopsys translate_off
initial
stage4_reg = 0;
// synopsys translate_on
always @ ( negedge clkin_wire or posedge reset)
if (reset == 1'b1) stage4_reg <= 1'b0;
else stage4_reg <= (wire_stage_cntr_q[1] & (~ wire_stage_cntr_q[0]));
assign wire_mux211_dataout = (do_fast_read === 1'b1) ? end_add_cycle_mux_datab_wire : (wire_addbyte_cntr_q[1] & (~ wire_addbyte_cntr_q[0]));
assign
addr_overdie = 1'b0,
addr_overdie_pos = 1'b0,
addr_reg_overdie = {24{1'b0}},
b4addr_opcode = {8{1'b0}},
berase_opcode = {8{1'b0}},
busy = busy_wire,
busy_wire = (((((((((((((do_read_rdid | do_read_sid) | do_read) | do_fast_read) | do_write) | do_sec_prot) | do_read_stat) | do_sec_erase) | do_bulk_erase) | do_die_erase) | do_4baddr) | do_read_volatile) | do_fread_epcq) | do_read_nonvolatile),
clkin_wire = clkin,
clr_addmsb_wire = (((((wire_stage_cntr_q[1] & (~ wire_stage_cntr_q[0])) & end_add_cycle) & end_one_cyc_pos) | (((~ do_read) & (~ do_fast_read)) & clr_write_wire2)) | ((((do_sec_erase | do_die_erase) & (~ do_wren)) & (~ do_read_stat)) & end_operation)),
clr_endrbyte_wire = (((((do_read | do_fast_read) & (~ wire_gen_cntr_q[2])) & wire_gen_cntr_q[1]) & wire_gen_cntr_q[0]) | clr_read_wire2),
clr_read_wire = clr_read_reg,
clr_read_wire2 = clr_read_reg2,
clr_write_wire2 = 1'b0,
data0out_wire = wire_cyclone_asmiblock2_data0out,
data_valid = data_valid_wire,
data_valid_wire = dvalid_reg2,
datain_wire = {{4{1'b0}}},
dataout = {read_data_reg[7:0]},
dataout_wire = {{4{1'b0}}},
derase_opcode = {8{1'b0}},
do_4baddr = 1'b0,
do_bulk_erase = 1'b0,
do_die_erase = 1'b0,
do_fast_read = 1'b0,
do_fread_epcq = 1'b0,
do_freadwrv_polling = 1'b0,
do_memadd = 1'b0,
do_polling = ((do_write_polling | do_sprot_polling) | do_freadwrv_polling),
do_read = ((((~ read_rdid_wire) & (~ read_sid_wire)) & (~ sec_protect_wire)) & read_wire),
do_read_nonvolatile = 1'b0,
do_read_rdid = 1'b0,
do_read_sid = 1'b0,
do_read_stat = 1'b0,
do_read_volatile = 1'b0,
do_sec_erase = 1'b0,
do_sec_prot = 1'b0,
do_sprot_polling = 1'b0,
do_wait_dummyclk = 1'b0,
do_wren = 1'b0,
do_write = 1'b0,
do_write_polling = 1'b0,
do_write_volatile = 1'b0,
end1_cyc_gen_cntr_wire = ((wire_gen_cntr_q[2] & (~ wire_gen_cntr_q[1])) & (~ wire_gen_cntr_q[0])),
end1_cyc_normal_in_wire = (((((((((((~ wire_stage_cntr_q[0]) & (~ wire_stage_cntr_q[1])) & (~ wire_gen_cntr_q[2])) & wire_gen_cntr_q[1]) & wire_gen_cntr_q[0]) | ((~ ((~ wire_stage_cntr_q[0]) & (~ wire_stage_cntr_q[1]))) & end1_cyc_gen_cntr_wire)) | (do_read & end_read)) | (do_fast_read & end_fast_read)) | ((((do_write | do_sec_erase) | do_bulk_erase) | do_die_erase) & write_prot_true)) | (do_write & (~ pagewr_buf_not_empty[0]))) | ((do_read_stat & start_poll) & (~ st_busy_wire))),
end1_cyc_reg_in_wire = end1_cyc_normal_in_wire,
end_add_cycle = wire_mux211_dataout,
end_add_cycle_mux_datab_wire = (wire_addbyte_cntr_q[2] & wire_addbyte_cntr_q[1]),
end_fast_read = end_read_reg,
end_one_cyc_pos = end1_cyc_reg2,
end_one_cycle = end1_cyc_reg,
end_op_wire = ((((((((((((wire_stage_cntr_q[1] & (~ wire_stage_cntr_q[0])) & ((((((~ do_read) & (~ do_fast_read)) & (~ (do_write & shift_pgwr_data))) & end_one_cycle) | (do_read & end_read)) | (do_fast_read & end_fast_read))) | ((((wire_stage_cntr_q[1] & wire_stage_cntr_q[0]) & do_read_stat) & end_one_cycle) & (~ do_polling))) | ((((((do_read_rdid & end_one_cyc_pos) & wire_stage_cntr_q[1]) & wire_stage_cntr_q[0]) & wire_addbyte_cntr_q[2]) & wire_addbyte_cntr_q[1]) & (~ wire_addbyte_cntr_q[0]))) | (((start_poll & do_read_stat) & do_polling) & (~ st_busy_wire))) | ((((~ wire_stage_cntr_q[1]) & wire_stage_cntr_q[0]) & (do_wren | (do_4baddr | (do_bulk_erase & (~ do_read_stat))))) & end_one_cycle)) | ((((do_write | do_sec_erase) | do_bulk_erase) | do_die_erase) & write_prot_true)) | ((do_write & shift_pgwr_data) & end_pgwr_data)) | (do_write & (~ pagewr_buf_not_empty[0]))) | (((((wire_stage_cntr_q[1] & wire_stage_cntr_q[0]) & do_sec_prot) & (~ do_wren)) & (~ do_read_stat)) & end_one_cycle)) | ((((((wire_stage_cntr_q[1] & wire_stage_cntr_q[0]) & (do_sec_erase | do_die_erase)) & (~ do_wren)) & (~ do_read_stat)) & end_add_cycle) & end_one_cycle)) | (((wire_stage_cntr_q[1] & wire_stage_cntr_q[0]) & end_one_cycle) & ((do_write_volatile | do_read_volatile) | (do_read_nonvolatile & wire_addbyte_cntr_q[1])))),
end_operation = end_op_reg,
end_ophdly = end_op_hdlyreg,
end_pgwr_data = 1'b0,
end_read = end_read_reg,
end_read_byte = (end_rbyte_reg & (~ addr_overdie)),
fast_read_opcode = {8{1'b0}},
freadwrv_sdoin = 1'b0,
in_operation = busy_wire,
load_opcode = (((((~ wire_stage_cntr_q[1]) & (~ wire_stage_cntr_q[0])) & (~ wire_gen_cntr_q[2])) & (~ wire_gen_cntr_q[1])) & wire_gen_cntr_q[0]),
memadd_sdoin = add_msb_reg,
not_busy = busy_det_reg,
oe_wire = 1'b0,
pagewr_buf_not_empty = {1'b1},
rden_wire = rden,
rdid_opcode = {8{1'b0}},
rdummyclk_opcode = {8{1'b0}},
read_data_reg_in_wire = {read_dout_reg[7:0]},
read_opcode = 8'b00000011,
read_rdid_wire = 1'b0,
read_sid_wire = 1'b0,
read_wire = read_reg,
rflagstat_opcode = {8{1'b0}},
rnvdummyclk_opcode = {8{1'b0}},
rsid_opcode = {8{1'b0}},
rsid_sdoin = 1'b0,
rstat_opcode = {8{1'b0}},
scein_wire = (~ ncs_reg),
sdoin_wire = to_sdoin_wire,
sec_protect_wire = 1'b0,
secprot_opcode = {8{1'b0}},
secprot_sdoin = 1'b0,
serase_opcode = {8{1'b0}},
shift_opcode = shift_op_reg,
shift_opdata = stage2_wire,
shift_pgwr_data = 1'b0,
st_busy_wire = 1'b0,
stage2_wire = stage2_reg,
stage3_wire = stage3_reg,
stage4_wire = stage4_reg,
start_frpoll = 1'b0,
start_poll = ((start_wrpoll | start_sppoll) | start_frpoll),
start_sppoll = 1'b0,
start_wrpoll = 1'b0,
to_sdoin_wire = ((((((shift_opdata & asmi_opcode_reg[7]) | rsid_sdoin) | memadd_sdoin) | write_sdoin) | secprot_sdoin) | freadwrv_sdoin),
wren_opcode = {8{1'b0}},
wren_wire = 1'b1,
write_opcode = {8{1'b0}},
write_prot_true = 1'b0,
write_sdoin = 1'b0,
wrvolatile_opcode = {8{1'b0}};
endmodule //asmi_altasmi_parallel_gqd2
//VALID FILE
// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
module asmi (
addr,
clkin,
rden,
read,
reset,
busy,
data_valid,
dataout)/* synthesis synthesis_clearbox = 2 */;
input [23:0] addr;
input clkin;
input rden;
input read;
input reset;
output busy;
output data_valid;
output [7:0] dataout;
wire [7:0] sub_wire0;
wire sub_wire1;
wire sub_wire2;
wire [7:0] dataout = sub_wire0[7:0];
wire busy = sub_wire1;
wire data_valid = sub_wire2;
asmi_altasmi_parallel_gqd2 asmi_altasmi_parallel_gqd2_component (
.read (read),
.addr (addr),
.clkin (clkin),
.rden (rden),
.reset (reset),
.dataout (sub_wire0),
.busy (sub_wire1),
.data_valid (sub_wire2))/* synthesis synthesis_clearbox=2
clearbox_macroname = ALTASMI_PARALLEL
clearbox_defparam = "data_width=STANDARD;epcs_type=EPCS4;intended_device_family=Cyclone;lpm_hint=UNUSED;lpm_type=altasmi_parallel;page_size=1;port_bulk_erase=PORT_UNUSED;port_die_erase=PORT_UNUSED;port_en4b_addr=PORT_UNUSED;port_fast_read=PORT_UNUSED;port_illegal_erase=PORT_UNUSED;port_illegal_write=PORT_UNUSED;port_rdid_out=PORT_UNUSED;port_read_address=PORT_UNUSED;port_read_dummyclk=PORT_UNUSED;port_read_rdid=PORT_UNUSED;port_read_sid=PORT_UNUSED;port_read_status=PORT_UNUSED;port_sector_erase=PORT_UNUSED;port_sector_protect=PORT_UNUSED;port_shift_bytes=PORT_UNUSED;port_wren=PORT_UNUSED;port_write=PORT_UNUSED;use_asmiblock=ON;use_eab=ON;write_dummy_clk=0;" */;
endmodule
// ============================================================
// CNX file retrieval info
// ============================================================
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone"
// Retrieval info: CONSTANT: DATA_WIDTH STRING "STANDARD"
// Retrieval info: CONSTANT: EPCS_TYPE STRING "EPCS4"
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"
// Retrieval info: CONSTANT: LPM_HINT STRING "UNUSED"
// Retrieval info: CONSTANT: LPM_TYPE STRING "altasmi_parallel"
// Retrieval info: CONSTANT: PAGE_SIZE NUMERIC "1"
// Retrieval info: CONSTANT: PORT_BULK_ERASE STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_DIE_ERASE STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_EN4B_ADDR STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_FAST_READ STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_ILLEGAL_ERASE STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_ILLEGAL_WRITE STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_RDID_OUT STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_READ_ADDRESS STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_READ_DUMMYCLK STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_READ_RDID STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_READ_SID STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_READ_STATUS STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SECTOR_ERASE STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SECTOR_PROTECT STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SHIFT_BYTES STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_WREN STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_WRITE STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: USE_ASMIBLOCK STRING "ON"
// Retrieval info: CONSTANT: USE_EAB STRING "ON"
// Retrieval info: CONSTANT: WRITE_DUMMY_CLK NUMERIC "0"
// Retrieval info: USED_PORT: addr 0 0 24 0 INPUT NODEFVAL "addr[23..0]"
// Retrieval info: CONNECT: @addr 0 0 24 0 addr 0 0 24 0
// Retrieval info: USED_PORT: busy 0 0 0 0 OUTPUT NODEFVAL "busy"
// Retrieval info: CONNECT: busy 0 0 0 0 @busy 0 0 0 0
// Retrieval info: USED_PORT: clkin 0 0 0 0 INPUT NODEFVAL "clkin"
// Retrieval info: CONNECT: @clkin 0 0 0 0 clkin 0 0 0 0
// Retrieval info: USED_PORT: data_valid 0 0 0 0 OUTPUT NODEFVAL "data_valid"
// Retrieval info: CONNECT: data_valid 0 0 0 0 @data_valid 0 0 0 0
// Retrieval info: USED_PORT: dataout 0 0 8 0 OUTPUT NODEFVAL "dataout[7..0]"
// Retrieval info: CONNECT: dataout 0 0 8 0 @dataout 0 0 8 0
// Retrieval info: USED_PORT: rden 0 0 0 0 INPUT NODEFVAL "rden"
// Retrieval info: CONNECT: @rden 0 0 0 0 rden 0 0 0 0
// Retrieval info: USED_PORT: read 0 0 0 0 INPUT NODEFVAL "read"
// Retrieval info: CONNECT: @read 0 0 0 0 read 0 0 0 0
// Retrieval info: USED_PORT: reset 0 0 0 0 INPUT NODEFVAL "reset"
// Retrieval info: CONNECT: @reset 0 0 0 0 reset 0 0 0 0
// Retrieval info: GEN_FILE: TYPE_NORMAL asmi.v TRUE FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL asmi.qip TRUE FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL asmi.bsf FALSE TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL asmi_inst.v FALSE TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL asmi_bb.v FALSE TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL asmi.inc FALSE TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL asmi.cmp FALSE TRUE

11
fpga/syn/ip/pll.ppf Executable file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE pinplan>
<pinplan intended_family="Cyclone" variation_name="pll" megafunction_name="ALTPLL" specifies="all_ports">
<global>
<pin name="inclk0" direction="input" scope="external" source="clock" />
<pin name="c0" direction="output" scope="external" source="clock" />
<pin name="c1" direction="output" scope="external" source="clock" />
<pin name="locked" direction="output" scope="external" />
</global>
</pinplan>

4
fpga/syn/ip/pll.qip Executable file
View File

@ -0,0 +1,4 @@
set_global_assignment -name IP_TOOL_NAME "ALTPLL"
set_global_assignment -name IP_TOOL_VERSION "13.0"
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "pll.v"]
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll.ppf"]

335
fpga/syn/ip/pll.v Executable file
View File

@ -0,0 +1,335 @@
// megafunction wizard: %ALTPLL%
// GENERATION: STANDARD
// VERSION: WM1.0
// MODULE: altpll
// ============================================================
// File Name: pll.v
// Megafunction Name(s):
// altpll
//
// Simulation Library Files(s):
// altera_mf
// ============================================================
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 13.0.1 Build 232 06/12/2013 SP 1 SJ Full Version
// ************************************************************
//Copyright (C) 1991-2013 Altera Corporation
//Your use of Altera Corporation's design tools, logic functions
//and other software and tools, and its AMPP partner logic
//functions, and any output files from any of the foregoing
//(including device programming or simulation files), and any
//associated documentation or information are expressly subject
//to the terms and conditions of the Altera Program License
//Subscription Agreement, Altera MegaCore Function License
//Agreement, or other applicable license agreement, including,
//without limitation, that your use is for the sole purpose of
//programming logic devices manufactured by Altera and sold by
//Altera or its authorized distributors. Please refer to the
//applicable agreement for further details.
// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
module pll (
inclk0,
c0,
c1,
locked);
input inclk0;
output c0;
output c1;
output locked;
wire [5:0] sub_wire0;
wire sub_wire2;
wire [0:0] sub_wire6 = 1'h0;
wire [0:0] sub_wire3 = sub_wire0[0:0];
wire [1:1] sub_wire1 = sub_wire0[1:1];
wire c1 = sub_wire1;
wire locked = sub_wire2;
wire c0 = sub_wire3;
wire sub_wire4 = inclk0;
wire [1:0] sub_wire5 = {sub_wire6, sub_wire4};
altpll altpll_component (
.inclk (sub_wire5),
.clk (sub_wire0),
.locked (sub_wire2),
.activeclock (),
.areset (1'b0),
.clkbad (),
.clkena ({6{1'b1}}),
.clkloss (),
.clkswitch (1'b0),
.configupdate (1'b0),
.enable0 (),
.enable1 (),
.extclk (),
.extclkena ({4{1'b1}}),
.fbin (1'b1),
.fbmimicbidir (),
.fbout (),
.fref (),
.icdrclk (),
.pfdena (1'b1),
.phasecounterselect ({4{1'b1}}),
.phasedone (),
.phasestep (1'b1),
.phaseupdown (1'b1),
.pllena (1'b1),
.scanaclr (1'b0),
.scanclk (1'b0),
.scanclkena (1'b1),
.scandata (1'b0),
.scandataout (),
.scandone (),
.scanread (1'b0),
.scanwrite (1'b0),
.sclkout0 (),
.sclkout1 (),
.vcooverrange (),
.vcounderrange ());
defparam
altpll_component.clk0_divide_by = 7,
altpll_component.clk0_duty_cycle = 50,
altpll_component.clk0_multiply_by = 10,
altpll_component.clk0_phase_shift = "0",
altpll_component.clk1_divide_by = 7,
altpll_component.clk1_duty_cycle = 50,
altpll_component.clk1_multiply_by = 5,
altpll_component.clk1_phase_shift = "0",
altpll_component.compensate_clock = "CLK0",
altpll_component.inclk0_input_frequency = 35714,
altpll_component.intended_device_family = "Cyclone",
altpll_component.invalid_lock_multiplier = 5,
altpll_component.lpm_hint = "CBX_MODULE_PREFIX=pll",
altpll_component.lpm_type = "altpll",
altpll_component.operation_mode = "NORMAL",
altpll_component.pll_type = "AUTO",
altpll_component.port_activeclock = "PORT_UNUSED",
altpll_component.port_areset = "PORT_UNUSED",
altpll_component.port_clkbad0 = "PORT_UNUSED",
altpll_component.port_clkbad1 = "PORT_UNUSED",
altpll_component.port_clkloss = "PORT_UNUSED",
altpll_component.port_clkswitch = "PORT_UNUSED",
altpll_component.port_configupdate = "PORT_UNUSED",
altpll_component.port_fbin = "PORT_UNUSED",
altpll_component.port_inclk0 = "PORT_USED",
altpll_component.port_inclk1 = "PORT_UNUSED",
altpll_component.port_locked = "PORT_USED",
altpll_component.port_pfdena = "PORT_UNUSED",
altpll_component.port_phasecounterselect = "PORT_UNUSED",
altpll_component.port_phasedone = "PORT_UNUSED",
altpll_component.port_phasestep = "PORT_UNUSED",
altpll_component.port_phaseupdown = "PORT_UNUSED",
altpll_component.port_pllena = "PORT_UNUSED",
altpll_component.port_scanaclr = "PORT_UNUSED",
altpll_component.port_scanclk = "PORT_UNUSED",
altpll_component.port_scanclkena = "PORT_UNUSED",
altpll_component.port_scandata = "PORT_UNUSED",
altpll_component.port_scandataout = "PORT_UNUSED",
altpll_component.port_scandone = "PORT_UNUSED",
altpll_component.port_scanread = "PORT_UNUSED",
altpll_component.port_scanwrite = "PORT_UNUSED",
altpll_component.port_clk0 = "PORT_USED",
altpll_component.port_clk1 = "PORT_USED",
altpll_component.port_clk3 = "PORT_UNUSED",
altpll_component.port_clk4 = "PORT_UNUSED",
altpll_component.port_clk5 = "PORT_UNUSED",
altpll_component.port_clkena0 = "PORT_UNUSED",
altpll_component.port_clkena1 = "PORT_UNUSED",
altpll_component.port_clkena3 = "PORT_UNUSED",
altpll_component.port_clkena4 = "PORT_UNUSED",
altpll_component.port_clkena5 = "PORT_UNUSED",
altpll_component.port_extclk0 = "PORT_UNUSED",
altpll_component.port_extclk1 = "PORT_UNUSED",
altpll_component.port_extclk2 = "PORT_UNUSED",
altpll_component.port_extclk3 = "PORT_UNUSED",
altpll_component.valid_lock_multiplier = 1;
endmodule
// ============================================================
// CNX file retrieval info
// ============================================================
// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"
// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"
// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "0"
// Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"
// Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"
// Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1"
// Retrieval info: PRIVATE: BANDWIDTH_USE_CUSTOM STRING "0"
// Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0"
// Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"
// Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"
// Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0"
// Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0"
// Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"
// Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"
// Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "e0"
// Retrieval info: PRIVATE: DEVICE_FAMILY NUMERIC "11"
// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8"
// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "4"
// Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "1"
// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
// Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000"
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "40.000000"
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "20.000000"
// Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
// Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0"
// Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0"
// Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"
// Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"
// Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "28.000"
// Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000"
// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"
// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone"
// Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"
// Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "1"
// Retrieval info: PRIVATE: LOCK_LOSS_SWITCHOVER_CHECK STRING "0"
// Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"
// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available"
// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT1 STRING "ps"
// Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any"
// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
// Retrieval info: PRIVATE: MIRROR_CLK1 STRING "0"
// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "2"
// Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "1"
// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "40.00000000"
// Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "20.00000000"
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1"
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "1"
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz"
// Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "0"
// Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
// Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "0.00000000"
// Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "ps"
// Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0"
// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
// Retrieval info: PRIVATE: PLL_ENA_CHECK STRING "0"
// Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
// Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
// Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0"
// Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
// Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
// Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0"
// Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
// Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
// Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "0"
// Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0"
// Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"
// Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"
// Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"
// Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"
// Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"
// Retrieval info: PRIVATE: SPREAD_USE STRING "0"
// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"
// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
// Retrieval info: PRIVATE: STICKY_CLK1 STRING "1"
// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "0"
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
// Retrieval info: PRIVATE: USE_CLK0 STRING "1"
// Retrieval info: PRIVATE: USE_CLK1 STRING "1"
// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
// Retrieval info: PRIVATE: USE_CLKENA1 STRING "0"
// Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0"
// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "7"
// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "10"
// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
// Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "7"
// Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50"
// Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "5"
// Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "0"
// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "35714"
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"
// Retrieval info: CONSTANT: INVALID_LOCK_MULTIPLIER NUMERIC "5"
// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
// Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL"
// Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO"
// Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED"
// Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_USED"
// Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED"
// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_USED"
// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: VALID_LOCK_MULTIPLIER NUMERIC "1"
// Retrieval info: USED_PORT: @clk 0 0 6 0 OUTPUT_CLK_EXT VCC "@clk[5..0]"
// Retrieval info: USED_PORT: @extclk 0 0 4 0 OUTPUT_CLK_EXT VCC "@extclk[3..0]"
// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0"
// Retrieval info: USED_PORT: c1 0 0 0 0 OUTPUT_CLK_EXT VCC "c1"
// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"
// Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked"
// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
// Retrieval info: CONNECT: c1 0 0 0 0 @clk 0 0 1 1
// Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.ppf TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_bb.v FALSE
// Retrieval info: LIB_FILE: altera_mf
// Retrieval info: CBX_MODULE_PREFIX: ON

3
fpga/syn/ip/rom2ram.qip Executable file
View File

@ -0,0 +1,3 @@
set_global_assignment -name IP_TOOL_NAME "RAM initializer"
set_global_assignment -name IP_TOOL_VERSION "13.0"
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "rom2ram.v"]

518
fpga/syn/ip/rom2ram.v Executable file
View File

@ -0,0 +1,518 @@
// megafunction wizard: %RAM initializer%
// GENERATION: STANDARD
// VERSION: WM1.0
// MODULE: ALTMEM_INIT
// ============================================================
// File Name: rom2ram.v
// Megafunction Name(s):
// ALTMEM_INIT
//
// Simulation Library Files(s):
// lpm
// ============================================================
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 13.0.1 Build 232 06/12/2013 SP 1 SJ Full Version
// ************************************************************
//Copyright (C) 1991-2013 Altera Corporation
//Your use of Altera Corporation's design tools, logic functions
//and other software and tools, and its AMPP partner logic
//functions, and any output files from any of the foregoing
//(including device programming or simulation files), and any
//associated documentation or information are expressly subject
//to the terms and conditions of the Altera Program License
//Subscription Agreement, Altera MegaCore Function License
//Agreement, or other applicable license agreement, including,
//without limitation, that your use is for the sole purpose of
//programming logic devices manufactured by Altera and sold by
//Altera or its authorized distributors. Please refer to the
//applicable agreement for further details.
//altmem_init CBX_AUTO_BLACKBOX="ALL" DEVICE_FAMILY="Cyclone" INIT_TO_ZERO="NO" NUMWORDS=32768 PORT_ROM_DATA_READY="PORT_USED" ROM_READ_LATENCY=1 WIDTH=8 WIDTHAD=15 clock datain dataout init init_busy ram_address ram_wren rom_address rom_data_ready rom_rden
//VERSION_BEGIN 13.0 cbx_altmem_init 2013:06:12:18:03:33:SJ cbx_altsyncram 2013:06:12:18:03:33:SJ cbx_cycloneii 2013:06:12:18:03:33:SJ cbx_lpm_add_sub 2013:06:12:18:03:33:SJ cbx_lpm_compare 2013:06:12:18:03:33:SJ cbx_lpm_counter 2013:06:12:18:03:33:SJ cbx_lpm_decode 2013:06:12:18:03:33:SJ cbx_lpm_mux 2013:06:12:18:03:33:SJ cbx_mgl 2013:06:12:18:33:59:SJ cbx_stratix 2013:06:12:18:03:33:SJ cbx_stratixii 2013:06:12:18:03:33:SJ cbx_stratixiii 2013:06:12:18:03:33:SJ cbx_stratixv 2013:06:12:18:03:33:SJ cbx_util_mgl 2013:06:12:18:03:33:SJ VERSION_END
// synthesis VERILOG_INPUT_VERSION VERILOG_2001
// altera message_off 10463
//synthesis_resources = lpm_compare 2 lpm_counter 2 lut 30
//synopsys translate_off
`timescale 1 ps / 1 ps
//synopsys translate_on
module rom2ram_meminit_kqn
(
clock,
datain,
dataout,
init,
init_busy,
ram_address,
ram_wren,
rom_address,
rom_data_ready,
rom_rden) ;
input clock;
input [7:0] datain;
output [7:0] dataout;
input init;
output init_busy;
output [14:0] ram_address;
output ram_wren;
output [14:0] rom_address;
input rom_data_ready;
output rom_rden;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_off
`endif
tri0 [7:0] datain;
tri0 rom_data_ready;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_on
`endif
reg [0:0] capture_init;
reg [14:0] delay_addr;
wire [14:0] wire_delay_addr_ena;
reg [7:0] delay_data;
wire [7:0] wire_delay_data_ena;
reg [2:0] prev_state;
wire [2:0] wire_state_reg_d;
reg [2:0] state_reg;
wire [2:0] wire_state_reg_sclr;
wire [2:0] wire_state_reg_sload;
wire wire_addr_cmpr_aeb;
wire wire_addr_cmpr_alb;
wire wire_wait_cmpr_aeb;
wire wire_wait_cmpr_alb;
wire [14:0] wire_addr_ctr_q;
wire [0:0] wire_wait_ctr_q;
wire [0:0] addrct_eq_numwords;
wire [0:0] addrct_lt_numwords;
wire clken;
wire [7:0] dataout_w;
wire [0:0] done_state;
wire [0:0] idle_state;
wire [0:0] ram_write_state;
wire [0:0] reset_state_machine;
wire [0:0] rom_addr_state;
wire [0:0] rom_data_capture_state;
wire [0:0] state_machine_clken;
// synopsys translate_off
initial
capture_init = 0;
// synopsys translate_on
always @ ( posedge clock)
if (clken == 1'b1) capture_init <= ((init | capture_init) & (~ done_state));
// synopsys translate_off
initial
delay_addr[0:0] = 0;
// synopsys translate_on
always @ ( posedge clock)
if (wire_delay_addr_ena[0:0] == 1'b1) delay_addr[0:0] <= wire_addr_ctr_q[0:0];
// synopsys translate_off
initial
delay_addr[1:1] = 0;
// synopsys translate_on
always @ ( posedge clock)
if (wire_delay_addr_ena[1:1] == 1'b1) delay_addr[1:1] <= wire_addr_ctr_q[1:1];
// synopsys translate_off
initial
delay_addr[2:2] = 0;
// synopsys translate_on
always @ ( posedge clock)
if (wire_delay_addr_ena[2:2] == 1'b1) delay_addr[2:2] <= wire_addr_ctr_q[2:2];
// synopsys translate_off
initial
delay_addr[3:3] = 0;
// synopsys translate_on
always @ ( posedge clock)
if (wire_delay_addr_ena[3:3] == 1'b1) delay_addr[3:3] <= wire_addr_ctr_q[3:3];
// synopsys translate_off
initial
delay_addr[4:4] = 0;
// synopsys translate_on
always @ ( posedge clock)
if (wire_delay_addr_ena[4:4] == 1'b1) delay_addr[4:4] <= wire_addr_ctr_q[4:4];
// synopsys translate_off
initial
delay_addr[5:5] = 0;
// synopsys translate_on
always @ ( posedge clock)
if (wire_delay_addr_ena[5:5] == 1'b1) delay_addr[5:5] <= wire_addr_ctr_q[5:5];
// synopsys translate_off
initial
delay_addr[6:6] = 0;
// synopsys translate_on
always @ ( posedge clock)
if (wire_delay_addr_ena[6:6] == 1'b1) delay_addr[6:6] <= wire_addr_ctr_q[6:6];
// synopsys translate_off
initial
delay_addr[7:7] = 0;
// synopsys translate_on
always @ ( posedge clock)
if (wire_delay_addr_ena[7:7] == 1'b1) delay_addr[7:7] <= wire_addr_ctr_q[7:7];
// synopsys translate_off
initial
delay_addr[8:8] = 0;
// synopsys translate_on
always @ ( posedge clock)
if (wire_delay_addr_ena[8:8] == 1'b1) delay_addr[8:8] <= wire_addr_ctr_q[8:8];
// synopsys translate_off
initial
delay_addr[9:9] = 0;
// synopsys translate_on
always @ ( posedge clock)
if (wire_delay_addr_ena[9:9] == 1'b1) delay_addr[9:9] <= wire_addr_ctr_q[9:9];
// synopsys translate_off
initial
delay_addr[10:10] = 0;
// synopsys translate_on
always @ ( posedge clock)
if (wire_delay_addr_ena[10:10] == 1'b1) delay_addr[10:10] <= wire_addr_ctr_q[10:10];
// synopsys translate_off
initial
delay_addr[11:11] = 0;
// synopsys translate_on
always @ ( posedge clock)
if (wire_delay_addr_ena[11:11] == 1'b1) delay_addr[11:11] <= wire_addr_ctr_q[11:11];
// synopsys translate_off
initial
delay_addr[12:12] = 0;
// synopsys translate_on
always @ ( posedge clock)
if (wire_delay_addr_ena[12:12] == 1'b1) delay_addr[12:12] <= wire_addr_ctr_q[12:12];
// synopsys translate_off
initial
delay_addr[13:13] = 0;
// synopsys translate_on
always @ ( posedge clock)
if (wire_delay_addr_ena[13:13] == 1'b1) delay_addr[13:13] <= wire_addr_ctr_q[13:13];
// synopsys translate_off
initial
delay_addr[14:14] = 0;
// synopsys translate_on
always @ ( posedge clock)
if (wire_delay_addr_ena[14:14] == 1'b1) delay_addr[14:14] <= wire_addr_ctr_q[14:14];
assign
wire_delay_addr_ena = {15{(clken & rom_data_capture_state)}};
// synopsys translate_off
initial
delay_data[0:0] = 0;
// synopsys translate_on
always @ ( posedge clock)
if (wire_delay_data_ena[0:0] == 1'b1) delay_data[0:0] <= datain[0:0];
// synopsys translate_off
initial
delay_data[1:1] = 0;
// synopsys translate_on
always @ ( posedge clock)
if (wire_delay_data_ena[1:1] == 1'b1) delay_data[1:1] <= datain[1:1];
// synopsys translate_off
initial
delay_data[2:2] = 0;
// synopsys translate_on
always @ ( posedge clock)
if (wire_delay_data_ena[2:2] == 1'b1) delay_data[2:2] <= datain[2:2];
// synopsys translate_off
initial
delay_data[3:3] = 0;
// synopsys translate_on
always @ ( posedge clock)
if (wire_delay_data_ena[3:3] == 1'b1) delay_data[3:3] <= datain[3:3];
// synopsys translate_off
initial
delay_data[4:4] = 0;
// synopsys translate_on
always @ ( posedge clock)
if (wire_delay_data_ena[4:4] == 1'b1) delay_data[4:4] <= datain[4:4];
// synopsys translate_off
initial
delay_data[5:5] = 0;
// synopsys translate_on
always @ ( posedge clock)
if (wire_delay_data_ena[5:5] == 1'b1) delay_data[5:5] <= datain[5:5];
// synopsys translate_off
initial
delay_data[6:6] = 0;
// synopsys translate_on
always @ ( posedge clock)
if (wire_delay_data_ena[6:6] == 1'b1) delay_data[6:6] <= datain[6:6];
// synopsys translate_off
initial
delay_data[7:7] = 0;
// synopsys translate_on
always @ ( posedge clock)
if (wire_delay_data_ena[7:7] == 1'b1) delay_data[7:7] <= datain[7:7];
assign
wire_delay_data_ena = {8{(clken & rom_data_capture_state)}};
// synopsys translate_off
initial
prev_state = 0;
// synopsys translate_on
always @ ( posedge clock)
if (clken == 1'b1) prev_state <= state_reg;
// synopsys translate_off
initial
state_reg[0:0] = 0;
// synopsys translate_on
always @ ( posedge clock)
if (state_machine_clken == 1'b1)
if (wire_state_reg_sclr[0:0] == 1'b1) state_reg[0:0] <= 1'b0;
else if (wire_state_reg_sload[0:0] == 1'b1) state_reg[0:0] <= 1;
else state_reg[0:0] <= wire_state_reg_d[0:0];
// synopsys translate_off
initial
state_reg[1:1] = 0;
// synopsys translate_on
always @ ( posedge clock)
if (state_machine_clken == 1'b1)
if (wire_state_reg_sclr[1:1] == 1'b1) state_reg[1:1] <= 1'b0;
else if (wire_state_reg_sload[1:1] == 1'b1) state_reg[1:1] <= 1;
else state_reg[1:1] <= wire_state_reg_d[1:1];
// synopsys translate_off
initial
state_reg[2:2] = 0;
// synopsys translate_on
always @ ( posedge clock)
if (state_machine_clken == 1'b1)
if (wire_state_reg_sclr[2:2] == 1'b1) state_reg[2:2] <= 1'b0;
else if (wire_state_reg_sload[2:2] == 1'b1) state_reg[2:2] <= 1;
else state_reg[2:2] <= wire_state_reg_d[2:2];
assign
wire_state_reg_d = {(((~ state_reg[2]) & state_reg[1]) & state_reg[0]), ((~ state_reg[2]) & (state_reg[1] ^ state_reg[0])), ((~ state_reg[2]) & (~ state_reg[0]))};
assign
wire_state_reg_sclr = {{2{reset_state_machine}}, 1'b0},
wire_state_reg_sload = {{2{1'b0}}, reset_state_machine};
lpm_compare addr_cmpr
(
.aeb(wire_addr_cmpr_aeb),
.agb(),
.ageb(),
.alb(wire_addr_cmpr_alb),
.aleb(),
.aneb(),
.dataa(delay_addr),
.datab({15{1'b1}})
`ifndef FORMAL_VERIFICATION
// synopsys translate_off
`endif
,
.aclr(1'b0),
.clken(1'b1),
.clock(1'b0)
`ifndef FORMAL_VERIFICATION
// synopsys translate_on
`endif
);
defparam
addr_cmpr.lpm_width = 15,
addr_cmpr.lpm_type = "lpm_compare";
lpm_compare wait_cmpr
(
.aeb(wire_wait_cmpr_aeb),
.agb(),
.ageb(),
.alb(wire_wait_cmpr_alb),
.aleb(),
.aneb(),
.dataa(wire_wait_ctr_q),
.datab(1'b0)
`ifndef FORMAL_VERIFICATION
// synopsys translate_off
`endif
,
.aclr(1'b0),
.clken(1'b1),
.clock(1'b0)
`ifndef FORMAL_VERIFICATION
// synopsys translate_on
`endif
);
defparam
wait_cmpr.lpm_width = 1,
wait_cmpr.lpm_type = "lpm_compare";
lpm_counter addr_ctr
(
.clk_en(clken),
.clock(clock),
.cnt_en(ram_write_state),
.cout(),
.eq(),
.q(wire_addr_ctr_q),
.sclr(((~ state_reg[1]) & (~ state_reg[0])))
`ifndef FORMAL_VERIFICATION
// synopsys translate_off
`endif
,
.aclr(1'b0),
.aload(1'b0),
.aset(1'b0),
.cin(1'b1),
.data({15{1'b0}}),
.sload(1'b0),
.sset(1'b0),
.updown(1'b1)
`ifndef FORMAL_VERIFICATION
// synopsys translate_on
`endif
);
defparam
addr_ctr.lpm_direction = "UP",
addr_ctr.lpm_modulus = 32768,
addr_ctr.lpm_port_updown = "PORT_UNUSED",
addr_ctr.lpm_width = 15,
addr_ctr.lpm_type = "lpm_counter";
lpm_counter wait_ctr
(
.clk_en(clken),
.clock(clock),
.cnt_en(rom_addr_state),
.cout(),
.eq(),
.q(wire_wait_ctr_q),
.sclr((~ rom_addr_state))
`ifndef FORMAL_VERIFICATION
// synopsys translate_off
`endif
,
.aclr(1'b0),
.aload(1'b0),
.aset(1'b0),
.cin(1'b1),
.data({1{1'b0}}),
.sload(1'b0),
.sset(1'b0),
.updown(1'b1)
`ifndef FORMAL_VERIFICATION
// synopsys translate_on
`endif
);
defparam
wait_ctr.lpm_direction = "UP",
wait_ctr.lpm_modulus = 1,
wait_ctr.lpm_port_updown = "PORT_UNUSED",
wait_ctr.lpm_width = 1,
wait_ctr.lpm_type = "lpm_counter";
assign
addrct_eq_numwords = wire_addr_cmpr_aeb,
addrct_lt_numwords = wire_addr_cmpr_alb,
clken = 1'b1,
dataout = dataout_w,
dataout_w = delay_data,
done_state = ((state_reg[2] & (~ state_reg[1])) & (~ state_reg[0])),
idle_state = (((~ state_reg[2]) & (~ state_reg[1])) & (~ state_reg[0])),
init_busy = capture_init,
ram_address = delay_addr,
ram_wren = ram_write_state,
ram_write_state = (((~ state_reg[2]) & state_reg[1]) & state_reg[0]),
reset_state_machine = (ram_write_state & addrct_lt_numwords),
rom_addr_state = (((~ state_reg[2]) & (~ state_reg[1])) & state_reg[0]),
rom_address = wire_addr_ctr_q,
rom_data_capture_state = (((~ state_reg[2]) & state_reg[1]) & (~ state_reg[0])),
rom_rden = (((~ prev_state[2]) & (((~ prev_state[1]) & (~ prev_state[0])) | (prev_state[1] & prev_state[0]))) & (((~ state_reg[2]) & (~ state_reg[1])) & state_reg[0])),
state_machine_clken = (clken & ((idle_state & capture_init) | ((rom_data_capture_state | done_state) | (capture_init & (((~ (rom_addr_state & (~ rom_data_ready))) | (rom_addr_state & rom_data_ready)) | (ram_write_state & addrct_eq_numwords))))));
endmodule //rom2ram_meminit_kqn
//VALID FILE
// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
module rom2ram (
clock,
datain,
init,
rom_data_ready,
dataout,
init_busy,
ram_address,
ram_wren,
rom_address,
rom_rden);
input clock;
input [7:0] datain;
input init;
input rom_data_ready;
output [7:0] dataout;
output init_busy;
output [14:0] ram_address;
output ram_wren;
output [14:0] rom_address;
output rom_rden;
wire [14:0] sub_wire0;
wire sub_wire1;
wire [14:0] sub_wire2;
wire [7:0] sub_wire3;
wire sub_wire4;
wire sub_wire5;
wire [14:0] ram_address = sub_wire0[14:0];
wire ram_wren = sub_wire1;
wire [14:0] rom_address = sub_wire2[14:0];
wire [7:0] dataout = sub_wire3[7:0];
wire init_busy = sub_wire4;
wire rom_rden = sub_wire5;
rom2ram_meminit_kqn rom2ram_meminit_kqn_component (
.clock (clock),
.init (init),
.datain (datain),
.rom_data_ready (rom_data_ready),
.ram_address (sub_wire0),
.ram_wren (sub_wire1),
.rom_address (sub_wire2),
.dataout (sub_wire3),
.init_busy (sub_wire4),
.rom_rden (sub_wire5));
endmodule
// ============================================================
// CNX file retrieval info
// ============================================================
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone"
// Retrieval info: CONSTANT: INIT_FILE STRING "UNUSED"
// Retrieval info: CONSTANT: INIT_TO_ZERO STRING "NO"
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"
// Retrieval info: CONSTANT: LPM_HINT STRING "UNUSED"
// Retrieval info: CONSTANT: LPM_TYPE STRING "altmem_init"
// Retrieval info: CONSTANT: NUMWORDS NUMERIC "32768"
// Retrieval info: CONSTANT: PORT_ROM_DATA_READY STRING "PORT_USED"
// Retrieval info: CONSTANT: ROM_READ_LATENCY NUMERIC "1"
// Retrieval info: CONSTANT: WIDTH NUMERIC "8"
// Retrieval info: CONSTANT: WIDTHAD NUMERIC "15"
// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL "clock"
// Retrieval info: CONNECT: @clock 0 0 0 0 clock 0 0 0 0
// Retrieval info: USED_PORT: datain 0 0 8 0 INPUT NODEFVAL "datain[7..0]"
// Retrieval info: CONNECT: @datain 0 0 8 0 datain 0 0 8 0
// Retrieval info: USED_PORT: dataout 0 0 8 0 OUTPUT NODEFVAL "dataout[7..0]"
// Retrieval info: CONNECT: dataout 0 0 8 0 @dataout 0 0 8 0
// Retrieval info: USED_PORT: init 0 0 0 0 INPUT NODEFVAL "init"
// Retrieval info: CONNECT: @init 0 0 0 0 init 0 0 0 0
// Retrieval info: USED_PORT: init_busy 0 0 0 0 OUTPUT NODEFVAL "init_busy"
// Retrieval info: CONNECT: init_busy 0 0 0 0 @init_busy 0 0 0 0
// Retrieval info: USED_PORT: ram_address 0 0 15 0 OUTPUT NODEFVAL "ram_address[14..0]"
// Retrieval info: CONNECT: ram_address 0 0 15 0 @ram_address 0 0 15 0
// Retrieval info: USED_PORT: ram_wren 0 0 0 0 OUTPUT NODEFVAL "ram_wren"
// Retrieval info: CONNECT: ram_wren 0 0 0 0 @ram_wren 0 0 0 0
// Retrieval info: USED_PORT: rom_address 0 0 15 0 OUTPUT NODEFVAL "rom_address[14..0]"
// Retrieval info: CONNECT: rom_address 0 0 15 0 @rom_address 0 0 15 0
// Retrieval info: USED_PORT: rom_data_ready 0 0 0 0 INPUT NODEFVAL "rom_data_ready"
// Retrieval info: CONNECT: @rom_data_ready 0 0 0 0 rom_data_ready 0 0 0 0
// Retrieval info: USED_PORT: rom_rden 0 0 0 0 OUTPUT NODEFVAL "rom_rden"
// Retrieval info: CONNECT: rom_rden 0 0 0 0 @rom_rden 0 0 0 0
// Retrieval info: GEN_FILE: TYPE_NORMAL rom2ram.v TRUE FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL rom2ram.qip TRUE FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL rom2ram.bsf FALSE TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL rom2ram_inst.v FALSE TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL rom2ram_bb.v FALSE TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL rom2ram.inc FALSE TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL rom2ram.cmp FALSE TRUE
// Retrieval info: LIB_FILE: lpm

26
fpga/syn/sof2jic.cof Normal file
View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="US-ASCII" standalone="yes"?>
<cof>
<eprom_name>EPCS4</eprom_name>
<flash_loader_device>EP1C3</flash_loader_device>
<output_filename>output/zx_ula.jic</output_filename>
<n_pages>1</n_pages>
<width>1</width>
<mode>7</mode>
<hex_block>
<hex_filename>../../rom/testrom.hex</hex_filename>
<hex_addressing>relative</hex_addressing>
<hex_offset>0</hex_offset>
</hex_block>
<sof_data>
<user_name>Page_0</user_name>
<page_flags>1</page_flags>
<bit0>
<sof_filename>output/zx_ula.sof</sof_filename>
</bit0>
</sof_data>
<version>5</version>
<create_cvp_file>0</create_cvp_file>
<options>
<map_file>1</map_file>
</options>
</cof>

30
fpga/syn/zx_ula.qpf Executable file
View File

@ -0,0 +1,30 @@
# -------------------------------------------------------------------------- #
#
# Copyright (C) 1991-2009 Altera Corporation
# Your use of Altera Corporation's design tools, logic functions
# and other software and tools, and its AMPP partner logic
# functions, and any output files from any of the foregoing
# (including device programming or simulation files), and any
# associated documentation or information are expressly subject
# to the terms and conditions of the Altera Program License
# Subscription Agreement, Altera MegaCore Function License
# Agreement, or other applicable license agreement, including,
# without limitation, that your use is for the sole purpose of
# programming logic devices manufactured by Altera and sold by
# Altera or its authorized distributors. Please refer to the
# applicable agreement for further details.
#
# -------------------------------------------------------------------------- #
#
# Quartus II
# Version 9.0 Build 235 06/17/2009 Service Pack 2 SJ Web Edition
# Date created = 08:15:12 April 28, 2019
#
# -------------------------------------------------------------------------- #
QUARTUS_VERSION = "9.0"
DATE = "08:15:12 April 28, 2019"
# Revisions
PROJECT_REVISION = "zx_ula"

177
fpga/syn/zx_ula.qsf Executable file
View File

@ -0,0 +1,177 @@
# -------------------------------------------------------------------------- #
#
# Copyright (C) 1991-2009 Altera Corporation
# Your use of Altera Corporation's design tools, logic functions
# and other software and tools, and its AMPP partner logic
# functions, and any output files from any of the foregoing
# (including device programming or simulation files), and any
# associated documentation or information are expressly subject
# to the terms and conditions of the Altera Program License
# Subscription Agreement, Altera MegaCore Function License
# Agreement, or other applicable license agreement, including,
# without limitation, that your use is for the sole purpose of
# programming logic devices manufactured by Altera and sold by
# Altera or its authorized distributors. Please refer to the
# applicable agreement for further details.
#
# -------------------------------------------------------------------------- #
#
# Quartus II
# Version 9.0 Build 235 06/17/2009 Service Pack 2 SJ Web Edition
# Date created = 08:15:12 April 28, 2019
#
# -------------------------------------------------------------------------- #
#
# Notes:
#
# 1) The default values for assignments are stored in the file:
# zx_ula_assignment_defaults.qdf
# If this file doesn't exist, see file:
# assignment_defaults.qdf
#
# 2) Altera recommends that you do not modify this file. This
# file is updated automatically by the Quartus II software
# and any changes you make may be lost or overwritten.
#
# -------------------------------------------------------------------------- #
set_global_assignment -name FAMILY Cyclone
set_global_assignment -name DEVICE EP1C3T100C8
set_global_assignment -name TOP_LEVEL_ENTITY zx_ula
set_global_assignment -name ORIGINAL_QUARTUS_VERSION "9.0 SP2"
set_global_assignment -name PROJECT_CREATION_TIME_DATE "08:15:12 APRIL 28, 2019"
set_global_assignment -name LAST_QUARTUS_VERSION "13.0 SP1"
set_global_assignment -name USE_GENERATED_PHYSICAL_CONSTRAINTS OFF -section_id eda_blast_fpga
set_global_assignment -name MAX7000_DEVICE_IO_STANDARD "3.3-V LVTTL"
set_global_assignment -name VERILOG_INPUT_VERSION SYSTEMVERILOG_2005
set_global_assignment -name VERILOG_SHOW_LMF_MAPPING_MESSAGES OFF
set_global_assignment -name MAX7000_OPTIMIZATION_TECHNIQUE AREA
set_global_assignment -name FMAX_REQUIREMENT "14.4 MHz"
set_global_assignment -name FMAX_REQUIREMENT "14.4 MHz" -section_id clk14
set_global_assignment -name FMAX_REQUIREMENT "7.156 MHz" -section_id clkcpu
set_instance_assignment -name CLOCK_SETTINGS clkcpu -to clkcpu
set_global_assignment -name AUTO_RESOURCE_SHARING OFF
set_global_assignment -name AUTO_LCELL_INSERTION OFF
set_global_assignment -name FMAX_REQUIREMENT "32 MHz" -section_id clk32
set_instance_assignment -name CLOCK_SETTINGS clk32 -to clk32
set_global_assignment -name FMAX_REQUIREMENT "8 MHz" -section_id clk8
set_global_assignment -name FMAX_REQUIREMENT "4 MHz" -section_id clk4
set_instance_assignment -name CLOCK_SETTINGS clk8 -to "lpm_counter:wgcnt_rtl_1|dffs[1]"
set_instance_assignment -name CLOCK_SETTINGS clk4 -to "lpm_counter:wgcnt_rtl_1|dffs[2]"
set_global_assignment -name OPTIMIZE_HOLD_TIMING OFF
set_global_assignment -name FITTER_EFFORT "STANDARD FIT"
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output/
set_global_assignment -name FMAX_REQUIREMENT "7.156 MHz" -section_id clk7
set_global_assignment -name DUTY_CYCLE 40 -section_id clk7
set_global_assignment -name SAVE_DISK_SPACE OFF
set_global_assignment -name SMART_RECOMPILE ON
set_global_assignment -name POWER_USE_PVA OFF
set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING OFF
set_global_assignment -name SLOW_SLEW_RATE OFF
set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS OFF
set_global_assignment -name DEVICE_FILTER_PIN_COUNT 100
set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL"
set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "NO HEAT SINK WITH STILL AIR"
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to n_rd
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to n_wr
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to sd_cd
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to n_m1
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to n_mreq
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to n_rfsh
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to n_rstcpu
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to n_nmi
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
set_global_assignment -name USE_CONFIGURATION_DEVICE ON
set_global_assignment -name RESERVE_ASDO_AFTER_CONFIGURATION "USE AS REGULAR IO"
set_global_assignment -name CYCLONE_CONFIGURATION_DEVICE EPCS4
set_location_assignment PIN_1 -to va[10]
set_location_assignment PIN_2 -to va[5]
set_location_assignment PIN_3 -to vd[4]
set_location_assignment PIN_4 -to va[12]
set_location_assignment PIN_5 -to va[11]
set_location_assignment PIN_20 -to ps2_data
set_location_assignment PIN_21 -to ps2_clk
set_location_assignment PIN_22 -to chroma[0]
set_location_assignment PIN_23 -to chroma[1]
set_location_assignment PIN_24 -to chroma[2]
set_location_assignment PIN_25 -to csync
set_location_assignment PIN_26 -to vdac[5]
set_location_assignment PIN_27 -to vdac[4]
set_location_assignment PIN_28 -to vdac[3]
set_location_assignment PIN_29 -to vdac[2]
set_location_assignment PIN_34 -to vdac[1]
set_location_assignment PIN_35 -to vdac[0]
set_location_assignment PIN_36 -to snd_l
set_location_assignment PIN_37 -to snd_r
set_location_assignment PIN_38 -to sd_cd
set_location_assignment PIN_39 -to sd_cs
set_location_assignment PIN_40 -to sd_miso_tape_in
set_location_assignment PIN_41 -to sd_sck
set_location_assignment PIN_42 -to sd_mosi
set_location_assignment PIN_47 -to vd[2]
set_location_assignment PIN_48 -to vd[0]
set_location_assignment PIN_49 -to vd[7]
set_location_assignment PIN_50 -to vd[1]
set_location_assignment PIN_51 -to vd[6]
set_location_assignment PIN_52 -to n_mreq
set_location_assignment PIN_54 -to n_int
set_location_assignment PIN_55 -to n_nmi
set_location_assignment PIN_56 -to va[14]
set_location_assignment PIN_57 -to n_vrd
set_location_assignment PIN_65 -to va[16]
set_location_assignment PIN_68 -to va[18]
set_location_assignment PIN_69 -to va[15]
set_location_assignment PIN_70 -to va[13]
set_location_assignment PIN_71 -to n_vwr
set_location_assignment PIN_72 -to va[17]
set_location_assignment PIN_73 -to clkcpu
set_location_assignment PIN_74 -to n_wr
set_location_assignment PIN_75 -to n_rd
set_location_assignment PIN_76 -to a[14]
set_location_assignment PIN_77 -to a[15]
set_location_assignment PIN_78 -to a[13]
set_location_assignment PIN_79 -to vd[5]
set_location_assignment PIN_84 -to n_rstcpu
set_location_assignment PIN_85 -to n_m1
set_location_assignment PIN_86 -to n_rfsh
set_location_assignment PIN_87 -to vd[3]
set_location_assignment PIN_88 -to va[0]
set_location_assignment PIN_89 -to va[1]
set_location_assignment PIN_90 -to va[2]
set_location_assignment PIN_91 -to va[3]
set_location_assignment PIN_92 -to va[4]
set_location_assignment PIN_97 -to va[6]
set_location_assignment PIN_98 -to va[7]
set_location_assignment PIN_99 -to va[8]
set_location_assignment PIN_100 -to va[9]
set_global_assignment -name RESERVE_ALL_UNUSED_PINS "AS INPUT TRI-STATED WITH WEAK PULL-UP"
set_location_assignment PIN_53 -to n_iorq
set_location_assignment PIN_10 -to clk28
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/mixer.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/soundrive.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/screen.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/ports.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/magic.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/divmmc.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/cpucontrol.sv
set_global_assignment -name VERILOG_FILE ../rtl/chroma_gen.v
set_global_assignment -name VHDL_FILE ../rtl/ym2149.vhd
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/common.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/top.sv
set_global_assignment -name SDC_FILE clocks.sdc
set_global_assignment -name CDF_FILE output/zx_ula.cdf
set_global_assignment -name QIP_FILE ip/pll.qip
set_global_assignment -name QIP_FILE ip/rom2ram.qip
set_global_assignment -name QIP_FILE ip/asmi.qip
set_global_assignment -name ENABLE_SIGNALTAP OFF
set_global_assignment -name USE_SIGNALTAP_FILE stp1.stp
set_global_assignment -name SIGNALTAP_FILE stp1.stp
set_global_assignment -name SLD_FILE "stp1_auto_stripped.stp"
set_global_assignment -name RTLV_GROUP_RELATED_NODES OFF
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top