// 
// 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!
//
//

//`define DEBUG_SHOWREADS
//`define DEBUG_SHOWWRITES

// Memory Map:
//
// PIC Data Memory addressing is complicated.  See the Data Book for full explanation..
//
// Basically, each BANK contains 32 locations.  The lowest 16 locations in ALL Banks
// are really all mapped to the same bank (bank #0).  The first 8 locations are the Special
// registers like the STATUS and PC registers.  The upper 16 words in each bank, really are
// unique to each bank.  The smallest PIC (16C54) only has the one bank #0.
//
// So, as a programmer, what you get is this.  No matter what bank you are in (FSR[6:5])
// you always have access to your special registers and also to registers 8-15.  You can
// change to a 1 of 4 banks by setting FSR[6:5] and get 4 different sets of registers
// 16-31.
//
//
//   bank location 
//     XX 00rrr  -  The special registers are not implemented in this register file.
//     XX 01rrr  -  The 8 common words, just above the Special Regs, same for all Banks
//     00 1rrrr  -  The 16 words unique to Bank #0
//     01 1rrrr  -  The 16 words unique to Bank #1
//     10 1rrrr  -  The 16 words unique to Bank #2
//     11 1rrrr  -  The 16 words unique to Bank #3
//
//  So, 
//     Special Regs are location[4:3] == 00
//     Common Regs are  location[4:3] == 01
//     Words in banks   location[4]   == 1
// 
//  Remap to a new single memory space.  Remap in chunks of 8 words.  The PIC words
//  will get remapped to the RAM in a contiguous manner.  The Common registers are
//  mapped to the first 8 words of our RAM.  Next, each bank's words in the upper
//  half of the bank are mapped to the RAM in a contiguous manner:
//
//      PIC View        Our RAM
//   bank location      Address
//     00 01rrr  =>     0  -   7   (common words)
//     00 10rrr  =>     8  -  15
//     00 11rrr  =>    16  -  23
//     01 01rrr  =>     0  -   7   (common words)
//     01 10rrr  =>    24  -  31
//     01 11rrr  =>    32  -  39
//     10 01rrr  =>     0  -   7   (common words)
//     10 10rrr  =>    40  -  47
//     10 11rrr  =>    48  -  55
//     11 01rrr  =>     0  -   7   (common words)
//     11 10rrr  =>    56  -  63
//     11 11rrr  =>    64  -  71 <-- last two locations are not implemented
//
// 
//
module picregs (clk, reset, we, re, bank, location, din, dout);

input		clk;
input		reset;
input		we;
input		re;
input  [1:0]	bank;		// Bank 0,1,2,3
input  [4:0]	location;	// Location
input  [7:0]	din;		// Input 
output [7:0]	dout;		// Output 

// The top-level modulke, piccpu, is supposed to garuntee that re and we
// are asserted for only valid locations.  So, we don't need to worry about
// safely mapping invalid addresses.
//

reg [6:0]	final_address;

// Instatiate the final memory model.
//
picdram picdram (
   .clk		(clk),
   .address	(final_address),
   .we		(we),
   .din		(din),
   .dout	(dout)
);

// The final_address is our remapped address.  This combinational logic
// is performed immediate on the input address signals, before any latching.
// This is because a WRITE doesn't use the latched values whereas the READ does.
//
always @(bank or location) begin
   casex ({bank, location})
      // First, let's handle the locations that all get mirrored back
      // into the bank #0 words from 8-15.
      //
      7'b00_01XXX: final_address <= {4'b0000, location[2:0]};
      7'b01_01XXX: final_address <= {4'b0000, location[2:0]};
      7'b10_01XXX: final_address <= {4'b0000, location[2:0]};
      7'b11_01XXX: final_address <= {4'b0000, location[2:0]};
      
      // Now, handle words in the upper halves of each bank.
      //
      // Bank #0
      7'b00_10XXX: final_address <= {4'b0001, location[2:0]};
      7'b00_11XXX: final_address <= {4'b0010, location[2:0]};

      // Bank #1
      7'b01_10XXX: final_address <= {4'b0011, location[2:0]};
      7'b01_11XXX: final_address <= {4'b0100, location[2:0]};
      
      // Bank #2
      7'b10_10XXX: final_address <= {4'b0101, location[2:0]};
      7'b10_11XXX: final_address <= {4'b0110, location[2:0]};
      
      // Bank #3
      7'b11_10XXX: final_address <= {4'b0111, location[2:0]};
      7'b11_11XXX: final_address <= {4'b1000, location[2:0]};
      
      default:     final_address <= {4'b0000, location[2:0]};
   endcase
end

endmodule
<div align="center"><br /><script type="text/javascript"><!--
google_ad_client = "pub-7293844627074885";
//468x60, Created at 07. 11. 25
google_ad_slot = "8619794253";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script><br />&nbsp;</div>