// // SYNTHETIC PIC 3.0 5/1/98 // // This is a synthesizable Microchip 16C57 compatible // microcontroller. This core is not intended as a high fidelity model of // the PIC, but simply a way to offer a simple processor core to people // familiar with the PIC who also have PIC tools. // // pictest.v - top-level testbench (NOT SYNTHESIZABLE) // piccpu.v - top-level synthesizable module // picregs.v - register file instantiated under piccpu // picalu.v - ALU instantiated under piccpu // picidec.v - Instruction Decoder instantiated under piccpu // picdram.v - Memory model for the DATA memory (e.g. Register File) // picpram.v - Memory model for the PROGRAM memory. // convert.pl - Perl script used to translate MPLAB's "Disassembled Code" output // into the Verilog $readmemh compatible file // test*.asm - (note the wildcard..) Several test programs used // to help debug the verilog. I used MPLAB and the simulator // to develop these programs and get the expected results. // Then, I ran them on Verilog-XL where they appeared to // match. // // Copyright, Tom Coonan, '97. // Use freely, but not for resale as is. You may use this in your // own projects as desired. Just don't try to sell it as is! // // module picalu ( op, a, b, y, cin, cout, zout ); input [3:0] op; // ALU Operation input [7:0] a; // 8-bit Input a input [7:0] b; // 8-bit Input b output [7:0] y; // 8-bit Output input cin; output cout; output zout; // Reg declarations for outputs reg cout; reg zout; reg [7:0] y; // Internal declarations reg addercout; // Carry out straight from the adder itself. parameter [3:0] ALUOP_ADD = 4'b0000; parameter [3:0] ALUOP_SUB = 4'b1000; parameter [3:0] ALUOP_AND = 4'b0001; parameter [3:0] ALUOP_OR = 4'b0010; parameter [3:0] ALUOP_XOR = 4'b0011; parameter [3:0] ALUOP_COM = 4'b0100; parameter [3:0] ALUOP_ROR = 4'b0101; parameter [3:0] ALUOP_ROL = 4'b0110; parameter [3:0] ALUOP_SWAP = 4'b0111; always @(a or b or cin or op) begin case (op) // synopsys full_case parallel_case ALUOP_ADD: {addercout, y} <= a + b; ALUOP_SUB: {addercout, y} <= a - b; // Carry out is really "borrow" ALUOP_AND: {addercout, y} <= {1'b0, a & b}; ALUOP_OR: {addercout, y} <= {1'b0, a | b}; ALUOP_XOR: {addercout, y} <= {1'b0, a ^ b}; ALUOP_COM: {addercout, y} <= {1'b0, ~a}; ALUOP_ROR: {addercout, y} <= {a[0], cin, a[7:1]}; ALUOP_ROL: {addercout, y} <= {a[7], a[6:0], cin}; ALUOP_SWAP: {addercout, y} <= {1'b0, a[3:0], a[7:4]}; default: {addercout, y} <= {1'b0, 8'h00}; endcase end always @(y) zout <= (y == 8'h00); always @(addercout or op) if (op == ALUOP_SUB) cout <= ~addercout; // Invert adder's carry to get borrow else cout <= addercout; endmodule