`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, rst, clk_aux, irq_aux); // input output declarations input clk; input rst; input clk_aux; input[2:0] irq_aux; output[7:0] sevseg; output[3:0] anod; input ps2d; input ps2c; output r, g, b; output hs, vs; input[7:0] sw; input[2:0] btn; 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 reg[7:0] ld; reg[15:0] mastercnt; wire[15:0] mwire; assign mwire = mastercnt; wire[2:0] btnl; wire btnc0, btnc1, btnc2; reg btnc; always @(posedge clk) btnc = btnc0 | btnc1 | btnc2; wire btnu0, btnu1, btnu2; wire clk1; wire clk2; // the character memory of the vga card // the memory-adaptor wire[1:0] byte_type; assign byte_type = 2'b11; 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_w memadap_write_a (.dinbus(din_bus), .abus(addr_a), .enbus(gl_ena), .webus(gl_wea), .ssrbus (gl_ssra), .doutmem(gl_dia32), .amem (gl_addra32), .enmem(gl_ena32), .wemem(gl_wea32),.ssrmem(gl_ssra32), .type(byte_type)); */ 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(byte_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(clk1), .clk2(clk2), .rst(rst) ); // the LED block ledblock led_out ( .zf3(mwire[15:12]), .zf2(mwire[11:8]), .zf1(mwire[7:4]), .zf0(mwire[3:0]), .sevseg(sevseg), .anods(anod), .ce(1'b1), .clk(clk), .rst(rst) ); // the three buttons debouncer debounce0 ( .btnin(btn[0]), .bstate(btnl[0]), .btndown(btnc0), .btnup(btnu0), .clk(clk), .rst(rst)); debouncer debounce1 ( .btnin(btn[1]), .bstate(btnl[1]), .btndown(btnc1), .btnup(btnu1), .clk(clk), .rst(rst)); debouncer debounce2 ( .btnin(btn[2]), .bstate(btnl[2]), .btndown(btnc2), .btnup(btnu2), .clk(clk), .rst(rst)); // the PS/2 controller wire[7:0] dd; wire[7:0] ps2data; ps2control ps2control0 ( .ps2c (ps2c), .ps2d (ps2d), .data (ps2data), .rdy(ps2irq), .clk(clk), .rst(rst)); // the ascii-rom to decode keysyms wire[7:0] ascii_val; to_ascii_rom ascii_rom0 (.ps2data( ps2data ), .res1(ascii_val)); // the cpu /* gldata_CPU gldat1 ( .gl_ena (enmem|we_mem_cpu), .gl_dia (out_mem_cpu), .gl_doa (in_mem_cpu), .gl_addra_l(addr_mem_cpu[12:0]), .gl_wea(we_mem_cpu), .gl_ssra(4'b0), .gl_clka(clk_cpu)); assign cpu_en = readmem_cpu | writemem_cpu; wire[31:0] data_feed; wire[31:0] data_get; wire rack; assign data_feed = writemem_cpu ? data_cpu : 32'bz; assign data_cpu = rack ? data_get : 32'bz; wire[31:0] tosout; wire[31:0] debugout; assign addr_mem_cpu = writemem_cpu ? addr_mem_cpu_Write : addr_mem_cpu_Read; mem_adaptor_be_w memadap_cpu_Write (.dinbus(data_feed),.abus(addr_cpu), .enbus(writemem_cpu), .webus(writemem_cpu), .ssrbus(1'b0), .doutmem(out_mem_cpu), .amem(addr_mem_cpu_Write), .wemem(we_mem_cpu), .ssrmem(ssra_cpu), .type(cpu_dat_type)); mem_adaptor_be_r memadap_cpu_Read (.doutbus(data_get), .abus(addr_cpu), .enbus(readmem_cpu), .ssrbus(1'b0), .read_ack(rack), .dinmem(in_mem_cpu), .amem(addr_mem_cpu_Read), .enmem(enmem), .ssrmem(ssrb_cpu), .type(cpu_dat_type), .clk(clk_cpu)); cpu cpu0 (.addr(addr_cpu),.data(data_cpu), .readmem(readmem_cpu),.writemem(writemem_cpu),.waitrq(1'b0), .type(cpu_dat_type), .intrq(intrq_cpu), .rst(rst), .clk(clk_cpu),.tosout(tosout),.debugout(debugout)); */ wire clk_sram; wire locked; wire locked_sr; wire clk_cpu; wire clk_cpuQ; takt takt0 (.clk(clk), .clk1(clk1), .clk_cpu(clk_cpuQ), .clk_sram(clk_sram), .locked(locked), .rst(rst) ); wire rst_sec; // secondary reset of cpu wire rst_cpu = rst | rst_sec; wire waitcpu_ext = 0; 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] data; wire readmem; wire writemem; wire[2:0] irq_cpu; wire[1:0] type; cpu cpu0 ( .addr(addr), .data(data), .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; 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[31:0] sel_regs; reg[3:0] sel_C_reg; reg[3:0] sel_A_reg; wire switch_A_C = 0; always @(posedge clk_sram or posedge rst) begin if (rst) begin sel_C_reg <= 4'hd; sel_A_reg <= 4'h0; end else if (rst_sec) begin sel_C_reg <= sel_regs[11:8]; sel_A_reg <= sel_regs[3:0]; end else begin sel_C_reg <= sel_C_reg; sel_A_reg <= sel_A_reg; end end assign sel_D = (addr_bus[31:28] == 4'he); assign sel_C = (addr_bus[31:28] == sel_C_reg); assign sel_B = (addr_bus[31:28] == 4'hf); assign sel_A = (addr_bus[31:28] == sel_A_reg); 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) ); mem_sync_A main_mem_A (.addr(addr_bus), .data(datamem_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; 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), .addra({19'b0,addr_bus[12:0]}), .wea(wmem_B), .ssra(4'b0), .enb(enmem_b_vga), .dob(din_mem_b_vga), .addrb({19'b0,addr_mem_b_vga[12: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; delay delay_D ( .I((|enmem_D) & (~(|wmem_D))), .O(rd_last_D), .CLK(clk_cpu) ); rst_generator rst_gen0 ( .enmem(enmem_D), .wmem(wmem_D), .addr(addr), .rst_sec(rst_sec), .clk_cpu(clk_cpu), .clk_sram(clk_sram), .rst(rst) ); bank_sel_switch select_mem0 ( .enmem(enmemD), .wmem(wmemD), .addr(addr), .data(datamemD), .sel_regs(sel_regs), .clk_cpu(clk_cpu), .rst(rst) ); assign irq_cpu = 3'b0; // 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_C, datamem_A, dataout_sr) begin if (rd_last_A) data_i_bus_r = datamem_A; else if (rd_last_C) data_i_bus_r = dataout_sr; else data_i_bus_r = 32'bz; end assign data_i_bus = data_i_bus_r; // test ps2data always @(posedge clk) begin if (ps2irq) begin $display ( "ps2data = %h", ps2data ); end end /* // control of screen by ps2data reg[12:0] xpos, xpos1; reg[12:0] ypos, ypos1; reg[7:0] writechar; reg[2:0] stat_rd; reg[1:0] cnt; reg[12:0] gl_addra_c; reg[7:0] gl_dia_c; assign gl_addra = gl_addra_c; assign gl_dia = gl_dia_c; wire[12:0] xysum, xysum1; assign xysum = xpos + ypos; assign xysum1 = xpos1 + ypos1; `define linelen 133 always @(posedge clk2 or posedge rst) begin if (rst) begin gl_ena <= 1'b0; gl_wea <= 1'b0; gl_ssra <= 1'b0; gl_addra_c <= 13'b0; gl_dia_c <= 8'b0; cnt <= 0; stat_rd <= 0; xpos <= 10; ypos <= (2 * `linelen); xpos1 <= 10; ypos1 <= (2 * `linelen); writechar <= 8'h21; end else begin case (stat_rd) 0: begin gl_wea <= 0; gl_ssra <= 0; gl_ena <= 0; stat_rd <= 0; if (ps2irq) begin if (cnt == 0) begin writechar <= ps2data; stat_rd <= 3; case (ps2data) 8'h75: begin xpos1 <= xpos; if (ypos >= `linelen) ypos1 <= ypos - `linelen; else ypos1 <= ypos; stat_rd <= 3; end 8'h72: begin xpos1 <= xpos; if (ypos < (49 * `linelen)) ypos1 <= ypos + `linelen; else ypos1 <= ypos; stat_rd <= 3; end 8'h74: begin ypos1 <= ypos; if (xpos < (`linelen - 1)) xpos1 <= xpos + 1; else xpos1 <= xpos; stat_rd <= 3; end 8'h6b: begin ypos1 <= ypos; if (xpos > 0) xpos1 <= xpos - 1; else xpos1 <= xpos; stat_rd <= 3; end 8'hF0: begin cnt <= 1; stat_rd <= 0; end default: begin if (ascii_val != 8'hff) begin writechar <= ascii_val; stat_rd <= 2; end else begin stat_rd <= 0; end end endcase end else if (cnt == 1) begin stat_rd <= 0; cnt <= 0; end end end 2: begin gl_addra_c <= xysum; gl_dia_c <= writechar; gl_wea <= 1; gl_ssra <= 1; gl_ena <= 1; if (xpos < (`linelen - 1)) xpos <= xpos + 1; stat_rd <= 0; end 3: begin gl_addra_c <= xysum; gl_dia_c <= 8'h20; gl_wea <= 1; gl_ssra <= 1; gl_ena <= 1; stat_rd <= 4; end 4: begin gl_addra_c <= xysum; gl_dia_c <= 8'h20; gl_wea <= 0; gl_ssra <= 0; gl_ena <= 0; xpos <= xpos1; ypos <= ypos1; stat_rd <= 5; end 5: begin gl_addra_c <= xysum; gl_dia_c <= writechar; gl_wea <= 1; gl_ssra <= 1; gl_ena <= 1; stat_rd <= 0; end endcase end end */ // controls the leds always @(posedge clk or posedge rst) begin if (rst) ld <= 8'h00; else //ld <= ps2data & (~sw); ld <= debugout[7:0]; end // sets mastercnt from ps2data 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 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; reg 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 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 ps10; always @(posedge clk or posedge rst) begin if (rst) begin ps10 <= 1; end else begin if (~psreg[0]) begin ps10 <= 1; end else begin ps10 <= 0; end end end reg ps10_1; always @(posedge clk) ps10_1 <= ps10; wire rdy1 = ps10 & (~ps10_1); always @(posedge clk or posedge rst) begin if (rst) begin data <= 0; rdy <= 0; end else begin if (rdy1) data <= psreg[8:1]; if (rdy) rdy <= 0; else rdy <= rdy1; end end always @(negedge ps2c or posedge rst) begin if (rst) begin psreg <= 11'b11111111111; end else begin if (~psreg[0]) begin psreg <= {ps2d, 10'b1111111111}; end else begin psreg <= {ps2d, psreg[10:1]}; end 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