module pads( bus_address, bus_data, clock7m, CDAC, INT, READ, AS, LDS, BUSRST, CFGIN, CFGOUT, rd, sd, dtr, dsr, rts, cts, cd, bitclockref, sram_databus, sram_address, sram_oe, sram_we /* temporary debug signals */ // ,RST,rise, risebar, fall, fallbar ); /* 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 */ wire [23:1] bus_address; wire [15:0] bus_data; wire clock7m, CDAC; /* clocks */ wire INT; wire READ; wire AS; /* address strobe */ wire LDS; /* low data strobe */ /* configuration mode signals */ input BUSRST; /* bus reset */ input CFGIN; /* time to configure */ output CFGOUT; /* configure the next card */ // output rom_select; /* enable external configuration ROM */ wire BUSRST, CFGIN, CFGOUT, rom_select; /* RS232C signals leading to tranceiver */ input rd, dsr, cts, cd; output sd, dtr, rts; wire rd, dsr, cts, cd, sd, dtr, rts; /* reference clock for baud rate generator */ input bitclockref; wire bitclockref; /* signals leading to external buffer SRAM */ inout [7:0] sram_databus; output [12:0] sram_address; output sram_oe, sram_we; wire write_bus; /* temporary debug signals */ /* input RST; wire RST; output rise, risebar; output fall, fallbar; reg rise, risebar; reg fall, fallbar; always @(posedge RST or posedge write_bus) if (write_bus) begin rise=0; risebar=1; end else begin rise=1; risebar=0; end always @(negedge RST or posedge write_bus) if (write_bus) begin fall=0; fallbar=1; end else begin fall=1; fallbar=0; end */ /////////////////////////////////////// wire [11:0] recv_byte_count, send_byte_count; wire [7:0] sram_write_latch, byte_in, byte_out, divisor; wire [7:0] cpu_data_in, cpu_data_out, serial_in, serial_dataout; wire [3:0] rom_out; /* handles autoconfig and card selection */ config config( .BUSRST(BUSRST), .CFGIN(CFGIN), .CFGOUT(CFGOUT), .READ(READ), .AS(AS), .low_data_strobe(LDS), .address(bus_address), .data_bus8(bus_data[15:8]), .card_select(card_select), .enable(enable), .hard_enable(hard_enable), .soft_enable(soft_enable), .rom_select(rom_select), .rom_out(rom_out), .clock7m(clock7m) ); clockgen clockgen( .clock16x(clock16x), .clock1x(clock1x), .clock10(clock10), .watchdog(watchdog), .clockref(bitclockref), .divisor(divisor), .enable(enable)); wire [15:0] bus_data_out; // assign bus_data= (write_bus) ? bus_data_out: 16'bz; // assign bus_data[15:4]= (write_bus) ? bus_data_out[15:4]: 12'bz; // assign bus_data[3:0]= (rom_select) ? ~rom_out: // (write_bus) ? bus_data_out[3:0]: 4'bz; assign bus_data[15:12]= (rom_select) ? rom_out: (write_bus) ? bus_data_out[15:12]: 4'bz; assign bus_data[11:0]= (write_bus) ? bus_data_out[11:0]: 12'bz; wire [9:0] bus_data_in= {bus_data[12], bus_data[11], bus_data[7:0]}; /* All access from the cpu happens here */ cpu_access cpu_access ( .bus_data_in(bus_data_in), .bus_data_out(bus_data_out), .clock7m(clock7m), .write_bus(write_bus), .card_select(card_select), .bus_read_write(READ), .data_strobe(LDS), .f_select(bus_address[4:1]), .serial_data_in(cpu_data_in), .serial_data_out(cpu_data_out), .read(cpu_read_buffer), .write(cpu_write_buffer), .send_byte_count(send_byte_count), .receive_byte_count(recv_byte_count), .cts(cts), .cd(cd), .dsr(dsr), .rts(rts), .dtr(dtr), .divisor(divisor), .hard_enable(hard_enable), .soft_enable(soft_enable), .charmode(charmode)); assign sram_databus= (sram_oe) ? sram_write_latch: 8'bz; /* controls access to the external SRAM buffer */ buffer buffer( .cpu_dataout(cpu_data_in), .serial_dataout(serial_dataout), .CPUin(cpu_data_out), .serial_in(serial_in), .cpu_read_req(cpu_read_buffer), .cpu_write_req(cpu_write_buffer), .serial_read_req(serial_read_buffer), .serial_write_req(serial_write_buffer), .serial_read_done(serial_read_done), .sram_data(sram_databus), .sram_write_latch(sram_write_latch), .sram_addr(sram_address), .sram_output_enable(sram_oe), .sram_write_enable(sram_we), .recv_bytecount(recv_byte_count), .send_bytecount(send_byte_count), .clock7m(clock7m), .CDAC(CDAC), .enable(enable) ); /* the high level data sender. Transmits via low level serial transmitter */ senddata senddata( .datain(serial_dataout), .read_buffer(serial_read_buffer), .read_done_req(serial_read_done), .clock10(clock10), .clock7m(clock7m), .bytecount(send_byte_count), .byte(byte_out), .ready(ready), .enable(enable) ); /* low level serial transmitter */ shiftout shiftout(.byte(byte_out), .ready_req(ready), .clockref(bitclockref), .clock1x(clock1x), .sd(sd), .enable(enable)); wire interupt; assign INT= (interupt) ? 1'b0: 1'bz; /* The high level data receiver. Recieves via low level serial receiver */ recvdata recvdata( .dataout(serial_in), .write_buffer(serial_write_buffer), .clock7m(clock7m), .charmode(charmode), .interupt(interupt), .interupt_ack(cpu_read_buffer), .bytecount(recv_byte_count), .remove_byte(cpu_read_buffer), .cd(cd), .watchdog(watchdog), .byte(byte_in), .ready_req(byte_received), .enable(enable) ); /* low level serial receiver */ shiftin shiftin(.byteout(byte_in), .ready(byte_received), .clock16x(clock16x), .clockref(bitclockref), .rd(rd), .enable(enable)); endmodule module shiftout(byte, ready_req, clockref, clock1x, sd, enable); input [7:0] byte; input ready_req; input clockref, clock1x; output sd; input enable; wire [7:0] byte; wire clock1x; /* 1x send clock */ reg sd; reg [3:0] bitcount; reg stop; reg ready_ack, ready_req_reg; wire ready= ready_req_reg ^ ready_ack; always @(negedge clockref) ready_req_reg= ready_req; /* initial begin bitcount= 4'd12; ready_ack= 1'b0; end */ always @(posedge clockref) if (clock1x & enable) case ( bitcount ) 4'd0: begin ready_ack= ~ready_ack; /* reset for next byte */ sd = byte[0]; bitcount = 4'd1; end 4'd1: begin sd = byte[1]; bitcount=4'd2; end 4'd2: begin sd = byte[2]; bitcount=4'd3; end 4'd3: begin sd = byte[3]; bitcount=4'd4; end 4'd4: begin sd = byte[4]; bitcount=4'd5; end 4'd5: begin sd = byte[5]; bitcount=4'd6; end 4'd6: begin sd = byte[6]; bitcount=4'd7; end 4'd7: begin sd = byte[7]; bitcount=4'd8; stop=1'b1; /* send at least one stop bit */ end default: if(stop | ~ready) begin sd=1'b1; stop=1'b0; end else begin sd=1'b0; bitcount=4'd0; end endcase else if( ~enable ) begin /* initialize */ sd=1'b1; bitcount=4'd8; stop=1'b1; end endmodule /* this module generates all derived clocks */ module clockgen(clock16x, clock1x, clock10, watchdog, clockref, divisor, enable); output clock16x; /* 16x receive clock */ output clock1x; /* 1x transmit clock */ output clock10; /* byte clock = 1x clock / 10 */ output watchdog; /* slow clock prevents stalls if packets are incomplete */ input clockref; /* 7.37Mhz reference clock = 16x clock for 460kbps */ input [7:0] divisor; /* used to generate baud rates from reference clock */ input enable; /* enable/disable clocks */ wire clock16x; reg clock1x, clock10, watchdog; reg [7:0] count16x, count16x_next; reg [3:0] count1x, count1x_next; reg [3:0] count10, count10_next; reg [14:0] watchcount, watchcount_next; /* initial begin #10; clock1x=1'b0; clock10=1'b0; watchdog=1'b0; count16x=8'b1; count1x=4'b0; count10=4'b0; watchcount=15'd5; clock16x_pos=1'b0; count10=4'd10; end */ wire clockref; wire [7:0] divisor; assign clock16x= (count16x == 8'b0) ? 1'b1: 1'b0; always @(posedge clockref) if (enable) count16x= count16x_next; else count16x= divisor; always @(count16x or divisor) if (count16x == 8'b0) count16x_next= divisor; else count16x_next= count16x -1; always @(negedge clockref) if (enable & clock16x) count1x = #5 count1x_next; always @(negedge clockref) if (enable & clock16x & (count1x == 4'b0) ) clock1x= #5 1'b1; else clock1x= #5 1'b0; always @(enable or count1x) if (enable) count1x_next = #5 count1x - 1; else count1x_next= 4'd15; always @(posedge clockref) if (clock1x & enable) count10 = count10_next; always @(posedge clockref) if (enable & clock1x & (count10 == 4'b0) ) clock10=1'b1; else clock10=1'b0; always @(enable or count10) if (enable & count10 != 4'b0) count10_next = count10-1; else count10_next=4'd9; always @(posedge clockref) if (enable) watchcount = watchcount_next; else watchcount= 15'b0; always @(watchcount or watchdog) begin watchcount_next= watchcount -1; if (watchcount == 0) watchdog = 1'b1; else watchdog= 1'b0; end endmodule module senddata(datain, read_buffer, read_done_req, clock10, clock7m, bytecount, enable, byte, ready); /* connected to external buffer interface */ input [7:0] datain; output read_buffer; input read_done_req; /* to clock generator */ input clock10; input clock7m; /* to low level shifter */ output [7:0] byte; output ready; input [11:0] bytecount; /* how many bytes in the send buffer? */ input enable; wire [7:0] datain; reg read_buffer; wire [11:0] bytecount; reg [7:0] byte; reg ready; reg read_done_ack; wire read_done= read_done_req ^ read_done_ack; /* initial begin ready= 1'b0; read_buffer= 1'b0; read_done_ack= 1'b0; end */ // acknowledge byte from buffer, signal shiftout to send it out the port always @(posedge clock7m) if ( ~enable ) ready=1'b0; else if (clock10 & read_done) begin read_done_ack= ~read_done_ack; ready= ~ready; byte=datain; end // One every byte type, request byte from send buffer if any. always @(posedge clock7m) if ( ~enable ) read_buffer= 1'b0; else if (clock10 & bytecount != 12'b0) read_buffer= ~read_buffer; endmodule /* interface to 8k external SRAM */ `define CPU_READ 3'd0 `define SERIAL_READ 3'd1 `define SERIAL_WRITE 3'd2 `define CPU_WRITE 3'd3 `define IDLE 3'd4 module buffer( cpu_dataout, serial_dataout, CPUin, serial_in, cpu_read_req, cpu_write_req, serial_read_req, serial_write_req, serial_read_done, sram_data, sram_write_latch, sram_addr, sram_output_enable, sram_write_enable, send_bytecount, recv_bytecount, clock7m, CDAC, enable ); output [7:0] cpu_dataout; output [7:0] serial_dataout; input [7:0] CPUin; input [7:0] serial_in; input cpu_read_req, cpu_write_req, serial_read_req, serial_write_req; output serial_read_done; /* signals for controling external sram */ input [7:0] sram_data; output [7:0] sram_write_latch; output [12:0] sram_addr; output sram_output_enable, sram_write_enable; output [11:0] send_bytecount, recv_bytecount; input clock7m, CDAC; /* 7Mhz system clocks, 45 degress out of phase */ input enable; reg [12:0] sram_addr; reg sram_output_enable; wire sram_write_enable; wire [7:0] sram_data; reg [7:0] sram_write_latch; /* sram write data latch */ reg [7:0] cpu_dataout; reg [7:0] serial_dataout; wire [7:0] CPUin; wire [7:0] serial_in; reg [11:0] cpu_write_addr; reg [11:0] cpu_read_addr; reg [11:0] serial_in_addr; reg [11:0] serial_out_addr; wire cpu_read_req, cpu_write_req, serial_read_req, serial_write_req; reg serial_read_done; reg cpu_read_ack, cpu_write_ack, serial_read_ack, serial_write_ack; wire cpu_read = cpu_read_req ^ cpu_read_ack; wire cpu_write= cpu_write_req ^ cpu_write_ack; wire serial_read = serial_read_req ^ serial_read_ack; wire serial_write = serial_write_req ^ serial_write_ack; reg [11:0] send_bytecount, recv_bytecount; reg [2:0] state; /* initial begin state= 4'd8; sram_output_enable=1'b1; sram_chip_select=1'b1; send_bytecount=12'd0; recv_bytecount=12'd0; serial_read_done= 1'b0; cpu_read_ack= 1'b0; cpu_write_ack= 1'b0; serial_read_ack= 1'b0; serial_write_ack= 1'b0; serial_read_done= 1'b0; end */ initial begin cpu_write_addr=12'b0; cpu_read_addr=12'b0; serial_in_addr=12'b0; serial_out_addr=12'b0; end assign sram_write_enable= ~(sram_output_enable & ~clock7m & ~CDAC ); always @(posedge CDAC) if ( ~enable ) begin state=`IDLE; sram_output_enable=1'b0; end else casex ({cpu_read, cpu_write, serial_read, serial_write}) 4'b1???: begin sram_addr={1'b0,cpu_read_addr}; sram_output_enable=1'b0; state=`CPU_READ; end 4'b01??: begin sram_output_enable=1'b1; sram_addr={1'b1,cpu_write_addr}; sram_write_latch=CPUin; state=`CPU_WRITE; end 4'b0010: begin sram_addr={1'b1,serial_out_addr}; sram_output_enable=1'b0; state=`SERIAL_READ; end 4'b00?1: begin sram_output_enable=1'b1; sram_addr={1'b0,serial_in_addr}; sram_write_latch=serial_in; state=`SERIAL_WRITE; end default: begin sram_output_enable=1'b0; state=`IDLE; end endcase // always @(negedge clock7m) always @(negedge CDAC) if (~enable) begin cpu_read_ack= 1'b0; recv_bytecount=12'b0; serial_read_ack= 1'b0; send_bytecount= 12'b0; serial_write_ack= 1'b0; cpu_write_ack= 1'b0; serial_read_done= 1'b0; cpu_read_addr= serial_in_addr; serial_out_addr= cpu_write_addr; end else casex (state) `CPU_READ: begin cpu_read_ack= ~cpu_read_ack; cpu_read_addr= sram_addr[11:0] + 1; /* cpu_read_addr++ (saves a latch) */ cpu_dataout=sram_data; recv_bytecount= recv_bytecount - 1; end `SERIAL_READ: begin serial_read_ack= ~serial_read_ack; serial_out_addr= sram_addr[11:0]+1; serial_dataout=sram_data; send_bytecount= send_bytecount - 1; serial_read_done= ~serial_read_done; end `SERIAL_WRITE: begin serial_write_ack= ~serial_write_ack; serial_in_addr= sram_addr[11:0]+1; recv_bytecount= recv_bytecount + 1; end `CPU_WRITE: begin cpu_write_ack= ~cpu_write_ack; cpu_write_addr= sram_addr[11:0]+1; send_bytecount= send_bytecount + 1; end endcase // ALways @(negedge CDAC) // If ( ~enable ) serial_read_done= 1'b0; // Else if (state == `SERIAL_READ) serial_read_done= ~serial_read_done; endmodule /* define external signals to CPLD */ `define FLAG 8'h7E module recvdata(dataout, write_buffer, clock7m, charmode, interupt, interupt_ack, bytecount, remove_byte, cd, watchdog, byte, ready_req, enable); /* signals for buffering system */ output [7:0] dataout; output write_buffer; input clock7m; /* 7Mhz system clock */ output charmode; /* mode select. active for character by character mode, inactive for packet */ output interupt; /* goes to edge card interupt line */ input interupt_ack; /* active when data is read by cpu */ input [11:0] bytecount; /* tell cpu interface how many bytes are in the receive buffer */ input remove_byte; /* signal that the cpu has read a byte */ input cd; /* RS232 Carrier detect signal */ input watchdog; /* very slow ( ~120Hz ) clock used to signal CPU intervention when packet boundary detection fails */ /* signals for low level data receiver */ input [7:0] byte; /* byte received from port */ input ready_req; /* signal from uart that we have a byte */ input enable; reg [7:0] dataout; reg write_buffer; reg charmode; reg interupt; wire [7:0] byte; wire ready_req; reg ready_req_reg, ready_ack; wire ready= ready_req_reg ^ ready_ack; reg [2:0] sequence; /* sequence position in check for PPP signature */ reg unchecked; /* flag to indicate that bytes have been received since the last cpu read */ /* initialize */ /* initial begin write_buffer=1'b0; ready_ack=1'b0; end */ /* confine cross clock metastability headaches to ready flag */ always @(negedge clock7m) ready_req_reg=ready_req; always @(posedge clock7m) if ( ~enable ) begin write_buffer=1'b0; ready_ack= 1'b0; end else if (ready) begin dataout=byte; ready_ack= ~ready_ack; write_buffer= ~write_buffer; end always @(posedge clock7m) if ( remove_byte || interupt || ~enable ) unchecked=1'b0; else if ( ready || // watch on character in ( watchdog & (bytecount != 12'd0) ) ) unchecked=1'b1; // watch for straglers always @(posedge clock7m) if (interupt_ack || ~enable ) interupt=1'b0; // acknowledge cpu read else if ( ( ready & (dataout == `FLAG || charmode) ) || // normal interupt ( unchecked & watchdog ) ) interupt=1'b1; // watchdog always @(posedge clock7m) if (~cd || ~enable ) begin charmode=1; /* always start in character mode */ sequence= 3'd0; end else if ( ready ) begin if ( byte == 8'h7E ) sequence= 3'd1; else case (sequence) 3'd1: case (byte) 8'hFF: sequence = 3'd2; 8'h7D: sequence = 3'd6; /* alternate sequence */ default: sequence = 3'd0; endcase 3'd2: if (byte == 8'h7D) sequence = 3'd3; else sequence = 3'd0; 3'd3: if (byte == 8'h23) sequence = 3'd4; else sequence = 3'd0; 3'd4: if (byte == 8'hC0) sequence = 3'd5; else sequence = 3'd0; 3'd5: if (byte == 8'h21) charmode=0; /* PPP detected! */ else sequence = 3'd0; 3'd6: if (byte == 8'hDF) sequence = 3'd2; /* rejoin the main sequence */ else sequence = 3'd0; endcase end endmodule module shiftin(byteout, ready, clock16x, clockref, rd, enable); output [7:0] byteout; output ready; input clock16x; /* 16x recieve clock from clockgen */ input clockref; /* 7.3Mhz reference clock for buad rate generation */ input rd; /* rs232 receive data line from tranceiver */ input enable; reg [6:0] byte; reg [7:0] byteout; reg ready; reg [3:0] bitcount; reg [3:0] sample_num; wire rd; /* receive data line */ reg [0:3] bit4; reg hunt_startbit_req, hunt_startbit_ack; reg bitclock; reg clock16x_delay; // clock16x delayed by 45 degrees from clockref always @(negedge clockref) clock16x_delay = clock16x; // initial sample_num_next=4'b0; wire hunt_startbit = hunt_startbit_req ^ hunt_startbit_ack; always @(negedge clockref) if (~enable) begin hunt_startbit_req= 1'b1; ready=1'b0; end else if (bitclock & clock16x) casex (bitcount) 0: begin byte[0] = rd; bitcount = 4'd1; end 1: begin byte[1] = rd; bitcount= 4'd2; end 2: begin byte[2] = rd; bitcount= 4'd3; end 3: begin byte[3] = rd; bitcount= 4'd4; end 4: begin byte[4] = rd; bitcount= 4'd5; end 5: begin byte[5] = rd; bitcount= 4'd6; end 6: begin byte[6] = rd; bitcount= 4'd7; end 7: begin byteout={rd, byte[6:0]}; bitcount= 4'd8; ready= ~ready; hunt_startbit_req= ~hunt_startbit_req; end default: bitcount= 4'd0; // start bit endcase /* initial begin sample_num=4'b0; bitclock=1'b0; bitcount=4'd8; ready=1'b0; hunt_startbit_req= 1'b1; hunt_startbit_ack= 1'b0; end */ always @(sample_num) #1 if (sample_num == 4'd15) bitclock=1'b1; else bitclock=1'b0; always @(posedge clockref) if (~hunt_startbit & clock16x_delay) sample_num= sample_num + 1; else if (hunt_startbit) sample_num= 4'd10; always @(posedge clockref) if (~enable) hunt_startbit_ack= 1'b0; else if ( hunt_startbit & bit4 == 4'b1100 ) hunt_startbit_ack= ~hunt_startbit_ack; // always @(negedge clock16x) bit4= {bit4next[1:3], rd}; always @(negedge clockref) if (~enable) bit4= 4'b1111; else if (clock16x) bit4= {bit4[1:3], rd}; endmodule module cpu_access( bus_data_in, bus_data_out, clock7m, write_bus, card_select, data_strobe, bus_read_write, f_select, serial_data_in, serial_data_out, read, write, send_byte_count, receive_byte_count, cts, cd, dsr, rts, dtr, divisor, hard_enable, soft_enable, charmode ); /* signals connected to zorro bus */ input [9:0] bus_data_in; output [15:0] bus_data_out; input clock7m; /* signals controling the chips's bus interface */ output write_bus; input card_select; input data_strobe; /* active low. Active if address and data buses are settled */ input bus_read_write; input [3:0] f_select; /* signals connected to buffer system */ input [7:0] serial_data_in; output [7:0] serial_data_out; output read, write; input [11:0] send_byte_count; input [11:0] receive_byte_count; /* serial control signals */ input cts, cd, dsr; output rts, dtr; /* uart controls */ output [7:0] divisor; input hard_enable; output soft_enable; /* 1 = active. 0 = inactive */ input charmode; wire [9:0] bus_data_in; reg [15:0] bus_data_out, uart_state_latch; wire bus_read_write; reg write_bus; // wire [7:0] serial_data_in; wire [7:0] serial_data_out; reg read, write; /* read/write buffer */ reg rts, dtr; reg [7:0] divisor; reg soft_enable; reg started; /* initial begin divisor=8'b0; soft_enable=1'b0; started=1'b0; end */ // always @(negedge card_select) write_bus=1'b0; always @(posedge clock7m) if (~card_select) started=1'b0; else if (~data_strobe) started= 1'b1; /* master control function selector */ always @(posedge clock7m) if ( ~hard_enable ) begin write=1'b0; dtr= 1'b0; rts= 1'b0; end else if (card_select & ~data_strobe & ~bus_read_write) case ( f_select[2:0] ) /* function select */ 3'h0: begin /* send byte */ if (~started) write= ~write; end 3'h1: begin /* write status */ // rts= bus_data_in[12]; // dtr= bus_data_in[11]; rts= bus_data_in[9]; dtr= bus_data_in[8]; divisor= bus_data_in[7:0]; end 3'h2: begin /* write divisor */ divisor= bus_data_in[7:0]; end 3'h3: begin /* write rts */ rts= bus_data_in[0]; end 3'h4: begin /* write dtr */ dtr= bus_data_in[0]; end 3'h5: begin /* write enable */ soft_enable= bus_data_in[0]; end endcase always @(posedge clock7m) /* receive byte */ if (~hard_enable | ~soft_enable) read= 1'b0; else if ( bus_read_write & card_select & f_select[2:0] == 3'b0 & ~started) read= ~read; always @(posedge clock7m) if ( ~card_select | ~hard_enable) write_bus= 1'b0; else if (~data_strobe & bus_read_write) write_bus= 1'b1; /* For now, route bytes from the bus directly to the sram buffer. I may someday put a latch here, but right now I don't see the need */ assign serial_data_out= bus_data_in[7:0]; always @(f_select or soft_enable or cd or cts or dsr or send_byte_count or receive_byte_count or divisor or rts or dtr or charmode) case (f_select) /* read status */ 4'h1: uart_state_latch= {cd, cts, dsr, rts, dtr, charmode, soft_enable, 1'b0, divisor}; /* read divisor */ 4'h2: uart_state_latch= {8'h00, divisor}; /* read rts */ 4'h3: uart_state_latch= {15'b0, rts}; /* read dtr */ 4'h4: uart_state_latch= {15'b0, dtr}; /* read enable */ 4'h5: uart_state_latch= {15'b0, soft_enable}; /* read cd */ 4'h6: uart_state_latch= {15'b0, cd}; /* read cts */ 4'h7: uart_state_latch= {15'b0, cts}; /* read dsr */ 4'h8: uart_state_latch= {15'b0, dsr}; /* read # of bytes in send buffer */ 4'h9: uart_state_latch= {4'b0,send_byte_count}; /* read # of bytes in receive buffer */ default: uart_state_latch= {4'b0,receive_byte_count}; endcase always @(bus_data_out or f_select or uart_state_latch or bus_read_write or serial_data_in) if ({bus_read_write, f_select} == 5'h10) bus_data_out= {uart_state_latch[15:8], serial_data_in}; else bus_data_out= uart_state_latch; endmodule /* this module controls autoconfig and generates various selects */ module config( BUSRST, CFGIN, CFGOUT, READ, AS, low_data_strobe, address, data_bus8, card_select, enable, hard_enable, soft_enable, rom_select, rom_out, clock7m); input BUSRST, CFGIN; output CFGOUT; input READ, AS, low_data_strobe; input [23:1] address; /* Zorro II address bus */ input [7:0] data_bus8; /* lower 8 bits of data bus */ output card_select; output enable; output hard_enable; input soft_enable; output rom_select; output [3:0] rom_out; input clock7m; reg CFGOUT; /* configure the next card */ // wire CFGOUT=1; // see if something hokey is going on wire card_select; /* notify other modules that it is ok to respond */ wire enable; /* active high if everthing is enabled */ reg hard_enable; /* disable low if told to reset by external signal */ wire soft_enable; /* disable low requested by software */ wire rom_select; reg [3:0] rom_out; reg [7:0] card_address; wire config_access, config_select; /* load card address */ assign config_access = ~CFGIN & CFGOUT & ~AS; assign config_select = (address[23:8] == 16'hE800 ); // assign config_select = (address[23:16] == 8'hE8 ); /* initial begin CFGOUT=1'b1; hard_enable=1'b0; end */ always @(posedge clock7m) if (~BUSRST | CFGIN ) CFGOUT=1'b1; else if ( config_access & config_select & ~READ & ({address[6:1],1'b0} == 7'h48) & ~low_data_strobe ) begin card_address = data_bus8; CFGOUT=1'b0; end /* enable configuration ROM */ assign rom_select = config_access & config_select & READ; /* enable normal interface */ assign card_select = ~AS & ~CFGOUT & (address[23:16] == card_address); always @(BUSRST or CFGIN) if (~BUSRST || CFGIN) hard_enable=1'b0; else hard_enable=1'b1; assign enable= hard_enable & soft_enable; always @(address[6:1] ) case ( {address[6:1], 1'b0} ) 7'h00: rom_out= { 2'b11, 1'b0, 1'b0 }; 7'h02: rom_out= ~{ 1'b0, 3'b001 }; 7'h04: rom_out= ~(4'h6); 7'h08: rom_out= ~{ 1'b0, 1'b1, 1'b0, 1'b1 }; 7'h10: rom_out= ~4'h4; 7'h14: rom_out= ~4'h2; default: rom_out= 4'b1111; endcase endmodule