`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: Jürgen Böhm // // Create Date: 02:08:39 02/18/2007 // Design Name: // Module Name: cpu // Project Name: // Target Devices: // Tool versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module comp_lt ( a, b, is_lt ); input[31:0] a,b; output reg is_lt; always @(a,b) begin if (a[31]==b[31]) is_lt <= (a[30:0] < b[30:0]); else is_lt <= a[31]; end endmodule module alu ( opcode, opA, opB, opC, aluOut, overflow, carry, zero, clk ); input[31:0] opA, opB, opC; output[31:0] aluOut; input[5:0] opcode; output overflow, carry, zero; input clk; reg[31:0] aluOut; assign zero = (aluOut == 0); // the comparators wire aLTb; wire aGTb; comp_lt comp_lt0 (opA, opB, aLTb ); comp_lt comp_lt1 (opB, opA, aGTb ); wire aEQb; wire aLTEb; wire aGTEb; assign aEQb = (opA == opB); assign aLTEb = aLTb | aEQb; assign aGTEb = aGTb | aEQb; // the main alu wire[31:0] lenVect = 32'd12 + (opA << 2); always @(posedge clk) begin case (opcode) 0: aluOut <= opA + opB; 1: aluOut <= opA - opB; 2: aluOut <= aLTEb ? 1 : opC; 3: aluOut <= aGTEb ? 1 : opC; 4: aluOut <= aLTb ? 1 : opC; 5: aluOut <= aGTb ? 1 : opC; 6: aluOut <= aEQb ? 1: opC; 11: aluOut <= opA | opB; 12: aluOut <= opA & opB; 13: aluOut <= ~(opA | opB); 14: begin case (opB[6:2]) 0: aluOut <= opA >> 0; 1: aluOut <= opA >> 1; 2: aluOut <= opA >> 2; 3: aluOut <= opA >> 3; 4: aluOut <= opA >> 4; 5: aluOut <= opA >> 5; 6: aluOut <= opA >> 6; 7: aluOut <= opA >> 7; 8: aluOut <= opA >> 8; 9: aluOut <= opA >> 9; 10: aluOut <= opA >> 10; 11: aluOut <= opA >> 11; 12: aluOut <= opA >> 12; 13: aluOut <= opA >> 13; 14: aluOut <= opA >> 14; 15: aluOut <= opA >> 15; 16: aluOut <= opA >> 16; 17: aluOut <= opA >> 17; 18: aluOut <= opA >> 18; 19: aluOut <= opA >> 19; 20: aluOut <= opA >> 20; 21: aluOut <= opA >> 21; 22: aluOut <= opA >> 22; 23: aluOut <= opA >> 23; 24: aluOut <= opA >> 24; 25: aluOut <= opA >> 25; 26: aluOut <= opA >> 26; 27: aluOut <= opA >> 27; 28: aluOut <= opA >> 28; 29: aluOut <= opA >> 29; 30: aluOut <= opA >> 30; 31: aluOut <= opA >> 31; endcase end 15: begin case (opB[6:2]) 0: aluOut <= opA << 0; 1: aluOut <= opA << 1; 2: aluOut <= opA << 2; 3: aluOut <= opA << 3; 4: aluOut <= opA << 4; 5: aluOut <= opA << 5; 6: aluOut <= opA << 6; 7: aluOut <= opA << 7; 8: aluOut <= opA << 8; 9: aluOut <= opA << 9; 10: aluOut <= opA << 10; 11: aluOut <= opA << 11; 12: aluOut <= opA << 12; 13: aluOut <= opA << 13; 14: aluOut <= opA << 14; 15: aluOut <= opA << 15; 16: aluOut <= opA << 16; 17: aluOut <= opA << 17; 18: aluOut <= opA << 18; 19: aluOut <= opA << 19; 20: aluOut <= opA << 20; 21: aluOut <= opA << 21; 22: aluOut <= opA << 22; 23: aluOut <= opA << 23; 24: aluOut <= opA << 24; 25: aluOut <= opA << 25; 26: aluOut <= opA << 26; 27: aluOut <= opA << 27; 28: aluOut <= opA << 28; 29: aluOut <= opA << 29; 30: aluOut <= opA << 30; 31: aluOut <= opA << 31; endcase end 32: if (|(opB[2:0])) begin aluOut <= {opB[31:3],3'b0} + 32'd8; end else begin aluOut <= opB; end 33: aluOut <= lenVect; 34: aluOut <= {opB[31:2],2'b10}; 35: aluOut <= {opB[31:2],2'b00} + opA; 36: aluOut <= opA + (opB >> 2); default : aluOut <= opB; endcase end endmodule module cpu( addr, data, readmem, writemem, intrq, type, rst, clk ); output[31:0] addr; inout[31:0] data; output readmem; output writemem; input intrq; output[1:0] type; input rst; input clk; //registered output lines reg readmem; reg writemem; reg[1:0] type; // special provision for data in/out reg[31:0] datao; reg dataeno; // assign data = dataeno ? datao : 32'bz; // registers reg[31:0] addro; assign addr = addro; reg[31:0] csp, dsp; // code stack pointer , data stack pointer reg[31:0] ir; reg[31:0] pc; wire[31:0] datamem; // data input buffer; wire[31:0] datamem2 = {datamem[29:0],2'b0}; reg[31:0] litbase; reg[31:0] template; reg[31:0] regA; reg[31:0] regB; reg[31:0] regC; reg[31:0] regD; reg[31:0] regE; reg[31:0] tos; wire[31:0] regA2 = {2'b0,regA[31:2]}; // the ALU wire[31:0] aluOut; wire[5:0] aluOp; wire overflow, carry, zero; wire[31:0] opA; alu alu0 (.opcode(aluOp),.opA(opA),.opB(tos),.opC(regC), .aluOut(aluOut),.overflow(overflow),.carry(carry),.zero(zero),.clk(clk)); wire[5:0] aluOp_h; assign aluOp = use_aluOp_h ? aluOp_h : ir[29:24]; wire is_nil = (tos == regC); // the bus structures and multiplexors // data bus // derived signal d from ir wire[31:0] d; wire[15:0] d1; assign d1 = ir[15:0]; assign d = {{14{d1[15]}},d1,1'b0,1'b0}; wire[31:0] litbase_plus_d = litbase + d; //assign d = 32'd4; wire[31:0] dsp_plus_d; wire[31:0] csp_plus_d; wire[31:0] dsp_minus_d; wire[31:0] csp_minus_d; assign dsp_plus_d = dsp + d; assign csp_plus_d = csp + d; assign dsp_minus_d = dsp - d; assign csp_minus_d = csp - d; wire[31:0] dsp_4; wire[31:0] dsp_8; wire[31:0] csp_4; wire[31:0] dsp_m_4; wire[31:0] csp_m_4; assign csp_4 = csp + 32'd4; assign dsp_m_4 = dsp - 32'd4; assign csp_m_4 = csp - 32'd4; assign dsp_4 = dsp + 32'd4; assign dsp_8 = dsp + 32'd8; wire[31:0] dsp_plus_dm1 = dsp_m_4 + d; wire[31:0] litbase_addr = template + 32'd16; wire[31:0] tp_4 = template + 32'd4; wire[31:0] pc_4 = pc + 32'd4; wire[31:0] regA_8 = regA + 32'd8; // dat reg[31:0] datbus; assign opA = datbus; wire[4:0] dat_source; `define vect_header_tag 32'd5 `define clos_header_tag 32'd13 `define val_3 32'd3 `define val_8 32'd8 `define val_12 32'd12 `define val_16 32'd16 always @(regA, regB, regC, regD, regE, litbase, datamem, aluOut, dat_source, tos, litbase_addr, template) begin case (dat_source) 0: begin datbus <= datamem; end 1: begin datbus <= aluOut; end 2: begin datbus <= regA; end 3: begin datbus <= regB; end 4: begin datbus <= regC; end 5: begin datbus <= regD; end 6: begin datbus <= litbase; end 7: begin datbus <= tos; end 8: begin datbus <= litbase_addr; end 9: begin datbus <= template; end 10: begin datbus <= regE; end 11: begin datbus <= pc_4; end 12: begin datbus <= d; end 13: begin datbus <= datamem2; end 14: begin datbus <= regA2; end 16: begin datbus <= `val_8; end 17: begin datbus <= `val_12; end 18: begin datbus <= `val_16; end 19: begin datbus <= `val_3; end 20: begin datbus <= `vect_header_tag; end 21: begin datbus <= `clos_header_tag; end 23: begin datbus <= 32'h0; end 24: begin datbus <= 32'h01020304; end default: begin datbus <= regA; end endcase end wire[4:0] dat_dest; reg[31:0] dummy; always @(posedge clk) begin case (dat_dest) 1: ir <= datbus; 3: tos <= datbus; 4: regA <= datbus; 5: regB <= datbus; 6: regC <= datbus; 7: regD <= datbus; 8: litbase <= datbus; 9: template <= datbus; 10: regA <= regA + 4; 11: regE <= datbus; 12: tos <= tos + 4; 13: tos <= tos - 4; default: dummy <= datbus; endcase end // data out bus assign datamem = ~dataeno ? data : 32'bz; assign data = dataeno ? datbus : 32'bz; // addr wire[4:0] addr_source; `define niladdr 32'h0000 always @(dsp, dsp_4, dsp_m_4, dsp_plus_d, csp, csp_4, csp_m_4, csp_plus_d, pc, aluOut, litbase, regA, regB, regD, addr_source) begin case (addr_source) 5'd0: addro <= dsp; 5'd1: addro <= dsp_4; 5'd2: addro <= dsp_m_4; 5'd3: addro <= dsp_plus_d; 5'd4: addro <= csp; 5'd5: addro <= csp_4; 5'd6: addro <= csp_m_4; 5'd7: addro <= csp_plus_d; 5'd8: addro <= pc; 5'd9: addro <= aluOut; 5'd10: addro <= regA; 5'd11: addro <= regB; 5'd12: addro <= regD; 5'd13: addro <= litbase_plus_d; 5'd14: addro <= litbase_addr; 5'd15: addro <= dsp_plus_dm1; 5'd16: addro <= tos; 5'd17: addro <= regA_8; 5'd18: addro <= tp_4; 5'd29: addro <= 32'h40; 5'd30: addro <= `niladdr; default: addro <= 32'bz; endcase end // cdsp wire[2:0] cdsp_dest; wire[2:0] cdsp_source; reg[31:0] cdspbus; always @(csp, dsp, csp_plus_d, dsp_plus_d, csp_minus_d, dsp_minus_d, csp_4, dsp_4, csp_m_4, dsp_m_4, cdsp_source) begin case (cdsp_source) 3'd0: cdspbus <= csp_plus_d; 3'd1: cdspbus <= dsp_plus_d; 3'd2: cdspbus <= csp_minus_d; 3'd3: cdspbus <= dsp_minus_d; 3'd4: cdspbus <= csp_4; 3'd5: cdspbus <= dsp_4; 3'd6: cdspbus <= csp_m_4; 3'd7: cdspbus <= dsp_m_4; endcase end always @(posedge clk or posedge rst) if (rst) begin csp <= 32'h1000; dsp <= 32'h2000; end else begin case (cdsp_dest) 3'd0: csp <= cdspbus; 3'd1: dsp <= cdspbus; 3'd2: csp <= datbus; 3'd3: dsp <= datbus; default: begin dsp <= dsp; csp <= csp; end endcase end // pcb wire[2:0] pcb_source; always @(posedge clk) begin case (pcb_source) 3'd0: pc <= pc_4; 3'd1: pc <= pc + d; 3'd2: pc <= datbus; 3'd3: begin if (is_nil) begin pc <= pc + d; end else begin pc <= pc_4; end end default: pc <= pc; endcase end // control ir read reg irRead; // miscellaneous always @(dataeno) begin writemem <= dataeno; end // micro program control wire[31:0] mic_inst; wire[31:0] mic_inst_h; reg[9:0] micr_pc; wire[9:0] next_micr_pc; assign next_micr_pc = micr_pc + 1; assign addr_source = mic_inst[31:27]; assign dat_source = mic_inst[26:22]; assign dat_dest = mic_inst[21:17]; assign cdsp_source = mic_inst[16:14]; assign cdsp_dest = mic_inst[13:11]; assign pcb_source = mic_inst[10:8]; wire data_eno_mic = mic_inst[6:6]; wire read_mem = mic_inst[7:7]; wire[3:0] mic_next = mic_inst[3:0]; wire dispatch = mic_inst_h[6:6]; wire to_page_zero = mic_inst_h[7:7]; wire[1:0] mtyp = mic_inst_h[9:8]; assign aluOp_h = mic_inst_h[5:0]; assign use_aluOp_h = mic_inst_h[10:10]; always @(mtyp) begin type <= mtyp; end always @(read_mem) begin readmem <= read_mem; end always @(data_eno_mic) begin dataeno <= data_eno_mic; end // main always @(posedge clk or posedge rst) begin if (rst) begin micr_pc <= 63*16; end else begin if (to_page_zero) begin micr_pc <= {5'b0, mic_next}; end else if (dispatch) begin micr_pc <= {datamem[21:16],mic_next}; end else begin micr_pc <= {micr_pc[9:4],mic_next}; end end end micro_store mcs0 ( .address({micr_pc[9:0]}), .data(mic_inst), .read_en(1'b1), .ce(1'b1)); micro_store_1 mcs1 ( .address({micr_pc[9:0]}), .data(mic_inst_h), .read_en(1'b1), .ce(1'b1)); endmodule //----------------------------------------------------- // Design Name : rom_using_file // File Name : rom_using_file.v // Function : ROM using readmemh // Coder : Deepak Kumar Tala & JB //----------------------------------------------------- module micro_store ( address, data, read_en, // Read Enable ce // Chip Enable ); input[9:0] address; output[31:0] data; input read_en; input ce; reg[31:0] mem[0:1024] ; assign data = (ce && read_en) ? mem[address] : 32'b0; initial begin $readmemb("mainmask.micdata", mem); // memory_list is memory file end endmodule module micro_store_1 ( address, data, read_en, // Read Enable ce // Chip Enable ); input[9:0] address; output[31:0] data; input read_en; input ce; reg[31:0] mem[0:1024] ; assign data = (ce && read_en) ? mem[address] : 32'b0; initial begin $readmemb("auxmask.micdata", mem); // memory_list is memory file end endmodule module mem_sync ( addr, data, en, write, clk ); input[31:0] addr; inout[31:0] data; input[3:0] en; input[3:0] write; input clk; `define memsize (32*1024 - 1) reg[31:0] mem[0:`memsize]; reg[7:0] mem0[0:`memsize]; reg[7:0] mem1[0:`memsize]; reg[7:0] mem2[0:`memsize]; reg[7:0] mem3[0:`memsize]; reg[31:0] dataout; assign data = (~(|write) & (|en_r)) ? dataout : 32'bz; reg[3:0] en_r; reg[7:0] val0; reg[7:0] val1; reg[7:0] val2; reg[7:0] val3; always @(posedge clk) begin if (|write) begin if (write[0]) mem0[addr[16:2]] <= data[7:0]; if (write[1]) mem1[addr[16:2]] <= data[15:8]; if (write[2]) mem2[addr[16:2]] <= data[23:16]; if (write[3]) mem3[addr[16:2]] <= data[31:24]; en_r <= en; end else begin dataout <= {mem3[addr[16:2]],mem2[addr[16:2]],mem1[addr[16:2]],mem0[addr[16:2]]}; en_r <= en; end end integer i; reg[31:0] val; initial begin // $readmemh("main-mem-dump.txt", mem); $readmemh("akt-test.dump", mem); #1 for (i = 0; i < `memsize; i = i + 1) begin val = mem[i]; mem0[i] = val[7:0]; mem1[i] = val[15:8]; mem2[i] = val[23:16]; mem3[i] = val[31:24]; end end initial begin #499990 for (i = 0; i < `memsize; i = i + 1) begin mem[i] = {mem3[i],mem2[i],mem1[i],mem0[i]}; end $writememh("mem-result-dump.txt", mem); end endmodule