module amiga(D); inout [15:0] D; reg [23:1] A; wire [23:0] Areal={A, 1'b0}; wire [15:0] D; reg clock7m, CDAC; wire INT; reg READ, AS, LDS, UDS; reg BUSRST, CFGIN; wire CFGOUT; serial_board serial_board( .bus_address(A), .bus_data(D), .clock7m(clock7m), .CDAC(CDAC), .INT(INT), .READ(READ), .AS(AS), .LDS(LDS), .UDS(UDS), .BUSRST(BUSRST), .CFGIN(CFGIN), .CFGOUT(CFGOUT) ); initial begin clock7m=1'b0; CDAC=1'b0; end always #70 clock7m= ~clock7m; initial begin $recordvars; $recordvars("primitives", "drivers"); $stop; end initial begin #35; repeat (6000) #70 CDAC= ~CDAC; end reg [15:0] cpu_data_out; reg processor_write; assign D= (processor_write) ? cpu_data_out: 16'bz; reg trash; reg [15:0] data, bus_data; initial begin BUSRST=1'b1; CFGIN=1'b1; READ=1'b0; AS=1'b1; {A, trash} = 24'hE80044; @(posedge clock7m); $display("config board before us at 80h"); config_board(16'h0080); CFGIN=1'b0; $display("configure our board at 91h"); config_board(16'h0091); $display("config board after us at 92h"); config_board(16'h0092); cpu_read_bus(24'h920000, data, 1'b1, 1'b0); cpu_read_bus(24'h910000, data, 1'b1, 1'b0); cpu_write_bus(24'h800000, 16'hAAAA, 1'b0, 1'b0); cpu_write_bus(24'h910000, 16'hBBBB, 1'b0, 1'b0); cpu_write_bus(24'h920000, 16'hCCCC, 1'b0, 1'b0); cpu_write_bus(24'h91000A, 16'h0000, 1'b0, 1'b0); /* soft disable */ cpu_write_bus(24'h910002, 16'h0000, 1'b0, 1'b0); /* clear divisor, rts, dtr */ cpu_write_bus(24'h910004, 16'h0000, 1'b0, 1'b0); /* set divisor to 0 (460Kbps) */ cpu_write_bus(24'h910006, 16'h0001, 1'b0, 1'b0); /* set rts */ cpu_write_bus(24'h910008, 16'h0001, 1'b0, 1'b0); /* se dtr */ cpu_write_bus(24'h91000A, 16'h0001, 1'b0, 1'b0); /* soft enable */ $display("enabled at", $time); #100000; cpu_read_bus(24'h910014, data, 1'b1, 1'b0); cpu_read_bus(24'h910000, data, 1'b1, 1'b0); cpu_read_bus(24'h910000, data, 1'b1, 1'b0); cpu_read_bus(24'h910000, data, 1'b1, 1'b0); cpu_read_bus(24'h910000, data, 1'b1, 1'b0); cpu_read_bus(24'h910000, data, 1'b1, 1'b0); #120000 $finish; end // always @(clock7m) $display("databus=%h, address=%h, AS=%d, READ=%d, dsL=%d, dsH=%d, CFGIN=%d, CFGOUT=%d", // D, A, AS, READ, LDS, UDS, CFGIN, CFGOUT ); task config_board; input [31:16] board_address; begin cpu_read_bus(24'hE80000, data, 1'b1, 1'b0); cpu_read_bus(24'hE80004, data, 1'b1, 1'b0); cpu_read_bus(24'hE80008, data, 1'b1, 1'b0); cpu_read_bus(24'hE80010, data, 1'b1, 1'b0); cpu_read_bus(24'hE80014, data, 1'b1, 1'b0); cpu_read_bus(24'hE80018, data, 1'b1, 1'b0); cpu_read_bus(24'hE8001C, data, 1'b1, 1'b0); cpu_read_bus(24'hE80020, data, 1'b1, 1'b0); cpu_read_bus(24'hE80024, data, 1'b1, 1'b0); cpu_read_bus(24'hE80028, data, 1'b1, 1'b0); cpu_read_bus(24'hE8002C, data, 1'b1, 1'b0); cpu_write_bus(24'hE80044, {board_address[31:24],8'b0}, 1'b1, 1'b0); cpu_write_bus(24'hE80046, {board_address[27:24],12'b0}, 1'b1, 1'b0); cpu_write_bus(24'hE80048, {board_address[23:16],8'b0}, 1'b1, 1'b0); cpu_write_bus(24'hE8004A, {board_address[19:16],12'b0}, 1'b1, 1'b0); end endtask task cpu_read_bus; input [23:0] bus_address_in; output [15:0] bus_data_out; input upper_data_strobe_in, low_data_strobe_in; begin @(negedge clock7m); A=bus_address_in[23:1]; READ=1'b1; @(posedge clock7m); LDS=low_data_strobe_in; UDS=upper_data_strobe_in; AS=1'b0; @(posedge clock7m); @(posedge clock7m); @(negedge clock7m); LDS=1'b1; UDS=1'b1; AS=1'b1; if (~low_data_strobe_in) bus_data_out[7:0]= D[7:0]; if (~upper_data_strobe_in) bus_data_out[15:8]= D[15:8]; end endtask task cpu_write_bus; input [23:0] bus_address_in; input [15:0] bus_data_in; input upper_data_strobe_in, low_data_strobe_in; begin @(negedge clock7m); A=bus_address_in[23:1]; @(posedge clock7m); READ=1'b0; AS=1'b0; cpu_data_out= bus_data_in; processor_write=1'b1; @(posedge clock7m); LDS=low_data_strobe_in; UDS=upper_data_strobe_in; @(posedge clock7m); @(negedge clock7m); LDS=1'b1; UDS=1'b1; AS=1'b1; @(posedge clock7m); READ=1'b1; processor_write=1'b0; end endtask endmodule module tranceiver (rd, sd, dtr, dsr, rts, cts, cd); input sd, dtr, rts; output rd, dsr, cts, cd; reg rd, dsr, cts, cd; reg [7:0] i; initial begin rd=1'b0; dsr=1'b1; cd=1'b1; cts=1'b1; end initial begin rd=1'b1; #32000; #16300; for(i=1; i < 240; i= i+8'd3) begin $display("receiving %h", i); bytetoserial(i); end #6000; bytetoserial(8'd7); end task bytetoserial; input [7:0] byte; begin rd=1'b0; #2176; rd= byte[0]; #2176; rd= byte[1]; #2176; rd= byte[2]; #2176; rd= byte[3]; #2176; rd= byte[4]; #2176; rd= byte[5]; #2176; rd= byte[6]; #2176; rd= byte[7]; #2176; rd=1'b1; #2176; end endtask endmodule module serial_board( bus_address, bus_data, clock7m, CDAC, INT, READ, AS, LDS, UDS, BUSRST, CFGIN, CFGOUT ); /* bus interface signals */ input [23:1] bus_address; inout [15:0] bus_data; input clock7m, CDAC; /* clocks */ output INT; input READ; input AS; /* address strobe */ input LDS; /* low data strobe */ input UDS; /* upper data strobe */ /* configuration mode signals */ input BUSRST; /* bus reset */ input CFGIN; /* time to configure */ output CFGOUT; /* configure the next card */ wire BUSRST, CFGIN, CFGOUT; wire [7:0] sram_databus; wire [12:0] sram_address; wire [15:0] bus_data; wire INT; /* almost everything happens in one big CPLD */ wire [23:0] A= {bus_address, 1'b0}; pads serial_chip(.bus_address(bus_address[23:1]), .bus_data(bus_data), .clock7m(clock7m), .CDAC(CDAC), .INT(INT), .READ(READ), .AS(AS), .LDS(LDS), .BUSRST(BUSRST), .CFGIN(CFGIN), .CFGOUT(CFGOUT), .rd(rd), .sd(sd), .dtr(dtr), .dsr(dsr), .rts(rts), .cts(cts), .cd(cd), .bitclockref(bitclockref), .sram_databus(sram_databus), .sram_address(sram_address), .sram_oe(sram_oe), .sram_we(sram_we)); /* rs232 tranceiver */ tranceiver tranceiver( .rd(rd), .sd(sd), .dtr(dtr), .dsr(dsr), .rts(rts), .cts(cts), .cd(cd)); /* 8k SRAM contains 4k send and 4k receive buffers */ sram serbuffer( .databus(sram_databus), .address(sram_address), .cs(1'b0), .oe(sram_oe), .we(sram_we)); /* 14.67Mhz chrystal occilator for baud rate generator */ occilator serial_clock(bitclockref); /* Autoconfig ROM */ // config_rom config_rom( .address(bus_address[7:1]), .dataout(bus_data[3:0]), // .chip_enable(1'b0), .output_enable(rom_select)); endmodule module sram(databus, address, cs, oe, we); inout [7:0] databus; input [12:0] address; input cs, oe, we; wire [12:0] address; wire cs, oe, we; reg [7:0] mem [8191:0]; reg read; assign databus = (read) ? mem[address]: 8'bz; always @(negedge (oe | cs) ) #10 read=1'b1; always @(posedge (oe | cs)) #10 read=1'b0; // always @(posedge we ) if (~cs) #50 mem[address] = databus; always @(posedge we ) if (~cs) mem[address] = #5 databus; always @(databus or address or oe or we) $display("buffer[%h] = %h", address, mem[address]); endmodule module occilator(clockref); output clockref; reg clockref; initial clockref=1'b1; always #68 clockref= ~clockref; endmodule `include "serial_debug.v"