`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 09:25:36 11/21/2006 // Design Name: // Module Name: main // Project Name: // Target Devices: // Tool versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module main(clk, sevseg, anod, ps2d, ps2c, r, g, b, hs, vs, sw, btn, ld, addr_sr, data_io_0_sr, data_io_1_sr, ce_0_sr, ce_1_sr, oe_sr, we_sr, ub_0_sr, lb_0_sr, ub_1_sr, lb_1_sr, rxd, txd, rst, clk_aux ); // input output declarations input clk; input rst; input clk_aux; // rs232 receive data and transfer data input rxd; output txd; // 7-segment led block output[7:0] sevseg; output[3:0] anod; // ps/2 input input ps2d; input ps2c; // vga output output r, g, b; output hs, vs; // button input input[7:0] sw; input[2:0] btn; // led row output[7:0] ld; // sram interface section of input output; output[17:0] addr_sr; inout[15:0] data_io_0_sr; inout[15:0] data_io_1_sr; output ce_0_sr, ce_1_sr; output oe_sr; output we_sr; output ub_0_sr, lb_0_sr; output ub_1_sr, lb_1_sr; // declaring registers and assigns // leds (ld) and seven-segmend led (mastercnt) reg[7:0] ld; reg[15:0] mastercnt; wire[15:0] mwire; assign mwire = mastercnt; // the buttons wire[2:0] btnl; wire btnc0, btnc1, btnc2; reg btnc; always @(posedge clk) btnc = btnc0 | btnc1 | btnc2; wire btnu0, btnu1, btnu2; // the vga clocks wire clk1; // clk1 is input to vgacontrol, output by takt0 wire clk2; // clk2 is output from vgacontrol, derived from input clk1 wire locked; // clk cpu wire clk_cpu; // the character memory of the vga card // the memory-adaptor wire[1:0] byte_type; assign word_type = 2'b00; wire[23:0] vga_addrb; wire[31:0] vga_din; wire vga_en; wire[31:0] addr_b_vga = {8'b0, vga_addrb}; wire enb_vga = vga_en; wire[31:0] din_mem_b_vga; wire[31:0] addr_mem_b_vga; wire[3:0] enmem_b_vga; mem_adaptor_be_r memadap_read_b (.doutbus(vga_din), .abus(addr_b_vga), .enbus(enb_vga), .ssrbus (1'b0), .read_ack (rack_vga), .dinmem(din_mem_b_vga), .amem (addr_mem_b_vga), .enmem(enmem_b_vga), .type(word_type), .clk(clk2)); //the vga controller vgacontrol vgacontrol0 ( /*.auxin({8'b0,sw[7:0]}),*/ .en(vga_en), .addrout(vga_addrb), .datin(vga_din), .r(r), .g(g), .b(b), .hso(hs), .vso(vs), .clk(clk), .clk2(clk2), .rst(rst) ); // the three buttons //debouncer debounce0 ( .btnin(btn[0]), .bstate(btnl[0]), .btndown(btnc0), .btnup(btnu0), .clk(clk_cpu), .rst(rst)); //debouncer debounce1 ( .btnin(btn[1]), .bstate(btnl[1]), .btndown(btnc1), .btnup(btnu1), .clk(clk_cpu), .rst(rst)); debouncer debounce2 ( .btnin(btn[2]), .bstate(btnl[2]), .btndown(btnc2), .btnup(btnu2), .clk(clk_cpu), .rst(rst)); // the cpu reg[2:0] irq_aux; initial begin irq_aux = 3'b0; end wire clk_sram; wire clk_cpu_na; takt takt0 (.clk(clk), .clk1(clk1), .clk_cpu(clk_cpu_na), .clk_sram(clk_sram), .locked(locked), .rst(rst) ); wire rst_sec; // secondary reset of cpu reg r1; reg rst_cpu; always @(posedge clk_cpu or posedge rst) begin if (rst) r1 <= 1'b1; else r1 <= 1'b0; end always @(posedge clk_cpu or posedge rst) begin if (rst) rst_cpu <= 1'b1; else rst_cpu <= r1; end // wait logic /* reg[3:0] wait_ext_sync; initial begin wait_ext_sync = 4'b0; end always @(posedge clk_cpu) wait_ext_sync = {wait_ext_sync[2:0], sw[4]}; */ wire waitcpu_ext = sw[4]; wire[31:0] debugout; wire[31:0] tosout; wire waitcpu_r = 0; wire waitcpu_w = 0; wire waitcpu = waitcpu_r | waitcpu_w | waitcpu_ext; wire rdack; wire wrtack; wire rdack_A; wire rdack_B; wire wrtack_A; wire wrtack_B; assign rdack = rdack_A | rdack_B; assign wrtack = wrtack_A | wrtack_B; wire sel_A; wire sel_B; wire sel_C; wire sel_D; wire[31:0] addr; wire[31:0] datain; wire[31:0] dataout; wire readmem; wire writemem; wire[2:0] irq_cpu; wire[1:0] type; cpu cpu0 ( .addr(addr), .datain(datain), .dataout(dataout), .readmem(readmem), .writemem(writemem), .waitrq(waitcpu), .irq(irq_aux), .type(type), .rst(rst_cpu), .clk(clk_cpu), .tosout(tosout), .debugout(debugout)); wire[31:0] data_b_w; wire[31:0] data_b_r; wire[3:0] ssrmem; wire[3:0] ssrmem_w; wire[3:0] enmem; wire[3:0] enmem1; wire readmem_only = readmem & ~writemem; wire writemem_only = writemem & ~readmem; // assign data_b_w = (writemem_only & ~rdack_A) ? data : 32'bz; // assign data = rdack_A ? data_b_r : 32'bz; assign data_b_w = dataout; assign datain = data_b_r; wire[31:0] amem_w; wire[31:0] amem_r; wire[3:0] wmem; // bus section wire[3:0] enmem_bus; wire[3:0] wmem_bus; wire[31:0] data_o_bus; wire[31:0] data_i_bus; wire[31:0] addr_bus; mem_adaptor_be_w maw0_A (.dinbus(data_b_w), .abus(addr), .enbus(writemem_only), .webus(writemem_only), .ssrbus(1'b0), // .write_ack(wrtack_A), .doutmem(data_o_bus), .amem(amem_w), .enmem(enmem1), .wemem(wmem), .ssrmem(ssrmem_w), .type(type) ); //, .clk(clk)); mem_adaptor_be_r mar0_A (.doutbus(data_b_r), .abus(addr), .enbus(readmem_only), .ssrbus(1'b0), .read_ack (rdack_A), .dinmem(data_i_bus), .amem(amem_r), .enmem(enmem), .ssrmem(ssrmem), .type(type), .clk(clk_cpu)); // bus assigns // bank selects wire[15:0] sel_regs; reg[3:0] sel_C_reg; reg[3:0] sel_A_reg; wire switch_A_C = 0; /* initial begin sel_A_reg = 4'h0; sel_C_reg = 4'hd; end */ always @(posedge clk_cpu or posedge rst_cpu) begin if (rst_cpu) begin if (~(sw[5])) begin sel_C_reg = 4'hd; sel_A_reg = 4'h0; end else begin sel_C_reg = 4'h0; sel_A_reg = 4'hd; end end else begin sel_C_reg = sel_C_reg; sel_A_reg = sel_A_reg; end end wire sel_A_1, sel_B_1, sel_C_1, sel_D_1; assign sel_D_1 = (addr_bus[31:28] == 4'he); assign sel_C_1 = (addr_bus[31:28] == sel_C_reg); assign sel_B_1 = (addr_bus[31:28] == 4'hf); assign sel_A_1 = (addr_bus[31:28] == sel_A_reg); assign sel_A = sel_A_1 & ~sel_B_1 & ~sel_C_1 & ~sel_D_1; assign sel_B = ~sel_A_1 & sel_B_1 & ~sel_C_1 & ~sel_D_1; assign sel_C = ~sel_A_1 & ~sel_B_1 & sel_C_1 & ~sel_D_1; assign sel_D = ~sel_A_1 & ~sel_B_1 & ~sel_C_1 & sel_D_1; assign enmem_bus = enmem | enmem1; assign wmem_bus = wmem; assign addr_bus = (|wmem_bus) ? amem_w : amem_r; wire rd_last_A; wire rd_last_B; wire rd_last_C; wire rd_last_D; // A block assigns wire[3:0] enmem_A = enmem_bus & {4{sel_A}}; wire[3:0] wmem_A = wmem_bus & {4{sel_A}}; wire[31:0] datamem_A; assign datamem_A = ((|wmem_A) & (|enmem_A) & (~rd_last_A)) ? data_o_bus : 32'bz; delay delay_A ( .I((|enmem_A) & (~(|wmem_A))), .O(rd_last_A), .CLK(clk_cpu) ); wire[31:0] dataout_A; mem_sync_CPU main_mem_A (.addr(addr_bus), .data(datamem_A), .dataout(dataout_A), .en(enmem_A), .wen(wmem_A), .clk(clk_cpu), .rst(rst_cpu)); // B block assigns wire[3:0] enmem_B = enmem_bus & {4{sel_B}}; wire[3:0] wmem_B = wmem_bus & {4{sel_B}}; wire[31:0] datamem_B; wire[31:0] dataout_B; assign datamem_B = ((|wmem_B) & (|enmem_B) & (~rd_last_B)) ? data_o_bus : 32'bz; delay delay_B ( .I((|enmem_B) & (~(|wmem_B))), .O(rd_last_B), .CLK(clk_cpu) ); mem_sync_VGA main_mem_B ( .ena (enmem_B), .dia (datamem_B), .doa(dataout_B), .addra(addr_bus[14:0]), .wea(wmem_B), .ssra(4'b0), .enb(enmem_b_vga), .dob(din_mem_b_vga), .addrb(addr_mem_b_vga[14:0]), .clka(clk_cpu), .clkb(clk2)); // C block assigns wire[3:0] enmem_C = enmem_bus & {4{sel_C}}; wire[3:0] wmem_C = wmem_bus & {4{sel_C}}; wire[31:0] datamem_C; assign datamem_C = ((|wmem_C) & (|enmem_C) & (~rd_last_C)) ? data_o_bus : 32'bz; delay delay_C ( .I((|enmem_C) & (~(|wmem_C))), .O(rd_last_C), .CLK(clk_cpu) ); // D block assigns wire[3:0] enmem_D = enmem_bus & {4{sel_D}}; wire[3:0] wmem_D = wmem_bus & {4{sel_D}}; wire[31:0] datamem_D; assign datamem_D = ((|wmem_D) & (|enmem_D) & (~rd_last_D)) ? data_o_bus : 32'bz; wire rd_D; assign rd_D = (|enmem_D) & ~(|wmem_D); delay delay_D ( .I(rd_D), .O(rd_last_D), .CLK(clk_cpu) ); wire[31:0] dataout_D; reg[7:0] outdata_D; assign dataout_D = {outdata_D, 8'b0, 8'b0, 8'b0}; /* rst_generator rst_gen0 ( .enmem(enmem_D), .wmem(wmem_D), .addr(addr_bus), .rst_sec(rst_sec), .clk_cpu(clk_cpu), .clk_sram(clk_sram), .rst(rst_cpu) ); bank_sel_switch select_mem0 ( .enmem(enmem_D), .wmem(wmem_D), .addr(addr_bus), .data(datamem_D), .sel_regs(sel_regs), .clk_cpu(clk_cpu), .rst(rst_cpu) ); */ // the PS/2 controller wire[7:0] ps2data; wire ps2irq; ps2control ps2control0 ( .ps2c (ps2c), .ps2d (ps2d), .data (ps2data), .rdy(ps2irq), .clk(clk_cpu), .rst(rst_cpu)); wire sel_keyb_contr; assign sel_keyb_contr = rd_D & (addr_bus[9:0] == 10'h8); // the LED block reg[11:0] sevseg_ctrl; initial begin sevseg_ctrl = 12'b0000_1101_1100; end assign sevseg[7:0] = sevseg_ctrl[7:0]; assign anod[3:0] = sevseg_ctrl[11:8]; wire sel_sevsegled_reg; assign sel_sevsegled_reg = (|enmem_D) & (|wmem_D) & (addr_bus[9:0] == 10'hC); always @(posedge clk_cpu or posedge rst_cpu) begin if (rst_cpu) begin sevseg_ctrl <= 12'b0000_1101_1100; end else begin if (sel_sevsegled_reg) begin sevseg_ctrl <= {datamem_D[19:16], datamem_D[31:24]}; end end end // the rs232 receiver wire rxd_rcv_irq; wire[7:0] rxd_data; wire rxd_eofp; wire rxd_idle; async_receiver asr0 (.clk(clk_cpu), .rst (rst_cpu), .RxD(rxd), .RxD_data_ready(rxd_rcv_irq), .RxD_data(rxd_data), .RxD_endofpacket(rxd_eofp), .RxD_idle(rxd_idle)); wire sel_rxd_rcv; assign sel_rxd_rcv = rd_D & (addr_bus[9:0] == 10'h10); // the rs232 transmitter wire sel_txd_snd; assign sel_txd_snd = (|enmem_D) & (|wmem_D) & (addr_bus[9:0] == 10'h14); wire txd_busy; async_transmitter ast0 (.clk(clk_cpu), .rst(rst_cpu), .TxD_start(sel_txd_snd & ~txd_busy), .TxD_data(datamem_D[7:0]), .TxD(txd), .TxD_busy(txd_busy)); // assign txd = 1'b1; // the main irq generating loop for all bank D devices wire no_irq; assign no_irq = ~(|irq_aux); always @(posedge clk_cpu or posedge rst_cpu) begin if (rst_cpu) begin irq_aux <= 3'b0; end else begin if (ps2irq & no_irq) begin // $display ("irq received ps2data = %h", ps2data ); irq_aux <= 3'b1 & {1'b0,1'b0,sw[3]}; outdata_D <= ps2data; end else if (rxd_rcv_irq & no_irq) begin $display ("irq received rxd_data = %h", rxd_data ); irq_aux <= 3'b1 & {1'b0,1'b0,sw[7]}; outdata_D <= rxd_data; end else if ((|irq_aux) & (sel_keyb_contr | sel_rxd_rcv)) begin $display ( "irq resetted." ); irq_aux <= 3'b0; end end end // sram wire[19:0] addrmem_sr = addr_bus[19:0]; wire[31:0] datain_sr = datamem_C; wire[31:0] dataout_sr; wire[3:0] en_sr = enmem_C; wire[3:0] wen_sr = wmem_C; /* wire[17:0] addr_sr; wire[15:0] data_io_0_sr; wire[15:0] data_io_1_sr; wire ce_0_sr, ce_1_sr; wire oe_sr; wire we_sr; wire ub_0_sr, lb_0_sr; wire ub_1_sr, lb_1_sr; */ sram_block sram0 (.amem (addrmem_sr), .dmem_in(datain_sr), .dmem_out(dataout_sr), .en(en_sr), .wen(wen_sr), .addr_sr(addr_sr), .data_io_0(data_io_0_sr), .data_io_1(data_io_1_sr), .ce_0(ce_0_sr), .ce_1(ce_1_sr), .oe(oe_sr), .we(we_sr), .ub_0(ub_0_sr), .lb_0(lb_0_sr), .ub_1(ub_1_sr), .lb_1(lb_1_sr), .clk_cpu(clk_cpu), .clk_sram ( clk_sram ), .rst (rst) ); // the read bus connect reg[31:0] data_i_bus_r; always @(rd_last_A, rd_last_B, rd_last_C, dataout_A, rd_last_D, dataout_sr, dataout_D) begin if (rd_last_A) data_i_bus_r = dataout_A; else if (rd_last_B) data_i_bus_r = dataout_B; else if (rd_last_C) data_i_bus_r = dataout_sr; else if (rd_last_D) data_i_bus_r = dataout_D; else data_i_bus_r = 32'bz; end assign data_i_bus = data_i_bus_r; // controls the leds always @(posedge clk or posedge rst) begin if (rst) ld <= 8'h00; else //ld <= ps2data & (~sw); if (~sw[6]) ld <= {debugout[7:0]}; else ld <= {~txd_busy, txd, 6'b0}; end // sets mastercnt for debugging output always @(posedge clk or posedge rst) begin if (rst) begin mastercnt <= 800 - 1; end else begin if (sw[7]) begin if (sw[6]) mastercnt <= tosout[31:16]; else mastercnt <= tosout[15:0]; end else begin // if (sw[5]) // mastercnt <= {12'b0,{4{locked}}}; // else // mastercnt <= debugout[15:0]; end end end endmodule // a simple delay module delay ( I, O, CLK ); input I; output O; reg O; input CLK; always @(posedge CLK) O <= I; endmodule // /* module bank_sel_switch ( enmem, wmem, addr, data, sel_regs, clk_cpu, rst ); input[3:0] enmem; input[3:0] wmem; input[31:0] addr; input[31:0] data; output[15:0] sel_regs; reg[15:0] sel_regs; input clk_cpu; input rst; always @(posedge clk_cpu or posedge rst) begin if (rst) begin sel_regs = 16'hedf0; end else begin if (|enmem & |wmem & (addr[9:0] == 10'h4)) begin sel_regs = data[15:0]; end end end endmodule */ // the reset generator /* module rst_generator ( enmem, wmem, addr, rst_sec, clk_cpu, clk_sram, rst ); input[3:0] enmem; input[3:0] wmem; input[31:0] addr; output rst_sec; reg rst_sec; input clk_cpu; input clk_sram; input rst; wire reset_asked; always @(posedge clk_cpu or posedge rst) begin if (rst | rst_sec) begin reset_asked = 1'b0; // $display ( "reset asked zeroed = %h ", reset_asked ); // $stop; end else begin if (|enmem & |wmem & (addr[9:0] == 10'b0)) begin reset_asked = 1'b1; // $display ( "reset asked set = %h ", reset_asked ); // $stop; end else reset_asked = reset_asked; end end reg clk_cpu_old; always @(posedge clk_sram) begin clk_cpu_old <= clk_cpu; end wire sram_cyc_1 = clk_cpu & ~clk_cpu_old; reg[6:0] res_sec_cnt; reg[6:0] res_sec_cnt_old; always @(posedge clk_sram or posedge rst) begin if (rst) begin res_sec_cnt = 0; rst_sec = 1'b0; end else begin if (sram_cyc_1 & reset_asked & (res_sec_cnt == 0)) begin res_sec_cnt = 6; rst_sec = 1'b1; end else if (res_sec_cnt != 0) begin // $display ( "res_sec_cnt = %h sram_cyc_1 = %h", res_sec_cnt, sram_cyc_1 ); res_sec_cnt = res_sec_cnt - 1; rst_sec = 1'b1; end else begin if (rst_sec) // $display ("sram_cyc_1 = %h clk_sram = %h reset_asked = %h", sram_cyc_1, clk_sram, reset_asked); rst_sec = 1'b0; end res_sec_cnt_old = res_sec_cnt; end end endmodule */ module ps2control ( ps2c, ps2d, data, rdy, clk, rst); input ps2c; input ps2d; output data; output rdy; reg rdy; input clk, rst; reg[10:0] psreg; reg[7:0] data; reg[1:0] psc; always @(posedge clk or posedge rst) begin if (rst) psc <= 2'b11; else psc <= {psc[0], ps2c}; end wire ps0 = psreg[0]; always @(posedge clk or posedge rst) begin if (rst) begin psreg <= 11'h7ff; rdy <= 1'b0; end else begin if ((psc[1] & ~psc[0]) & ps0) begin // $display ( "clock edge received. "); psreg <= {ps2d, psreg[10:1]}; rdy <= 1'b0; end else if (~ps0) begin data <= psreg[8:1]; // $display ("key data received = %h", psreg[8:1] ); psreg <= 11'h7ff; rdy <= 1'b1; end else rdy <= 1'b0; end end endmodule /* module to_ascii_rom (ps2data, res1); input[7:0] ps2data; output[7:0] res1; reg[7:0] res1; reg[7:0] res; always @(res) begin case (res) 8'd32: res1 <= res; 8'hff: res1 <= res; default: res1 <= res + 8'd32; endcase end always @(ps2data) begin case (ps2data) //a b c d e 8'h1C:res=8'd65; 8'h32:res=8'd66; 8'h21:res=8'd67; 8'h23:res=8'd68; 8'h24:res=8'd69; //f g h i j 8'h2B:res=8'd70; 8'h34:res=8'd71; 8'h33:res=8'd72; 8'h43:res=8'd73; 8'h3B:res=8'd74; //k l m n o 8'h42:res=8'd75; 8'h4B:res=8'd76; 8'h3A:res=8'd77; 8'h31:res=8'd78; 8'h44:res=8'd79; //p q r s t 8'h4D:res=8'd80; 8'h15:res=8'd81; 8'h2D:res=8'd82; 8'h1B:res=8'd83; 8'h2C:res=8'd84; //u v w x y 8'h3C:res=8'd85; 8'h2A:res=8'd86; 8'h1D:res=8'd87; 8'h22:res=8'd88; 8'h35:res=8'd90; //z 8'h1A:res=8'd89; //space 8'h29:res=8'd32; default: res=8'hFF; endcase end endmodule */