// hub_mem /* ------------------------------------------------------------------------------- Copyright 2014 Parallax Inc. This file is part of the hardware description for the Propeller 1 Design. The Propeller 1 Design is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. The Propeller 1 Design is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with the Propeller 1 Design. If not, see . ------------------------------------------------------------------------------- */ // // Magnus Karlsson 20140818 RAM is now 64KB // // RR20140816 ROM to use new unscrambled code and preset with $readmemh // ROM is now 4KB ($F000..$FFFF) and preset with interpreter/booter/runner // RAM may be expanded to fill available space up to 60KB // RR20140816 Bigger Hub RAM & No ROM // RAM is 48KB and remaps 48-64KB to 32-48KB module hub_mem ( input clk_cog, input ena_bus, input w, input [3:0] wb, input [13:0] a, input [31:0] d, output [7:0] red, output [7:0] green, output [7:0] blue, input wire pix_clk, input wire signed [15:0] sx, // horizontal screen position (signed) input wire signed [15:0] sy, // vertical screen position (signed) output [31:0] q ); /* //RJA trying to replace ram with IP wire clka, ena, wea0, clkb, enb, web; wire [13:0] addra; wire [7:0] dina0; wire [7:0] douta0; wire [13:0] addrb; wire [7:0] dinb0; wire [7:0] doutb0; reg [7:0] ram_q3; reg [7:0] ram_q2; reg [7:0] ram_q1; reg [7:0] ram_q0; //wire ram_q0,ram_q1,ram_q2,ram_q3; blk_mem_gen_0 ram0(clka, ena, wea0, addra, dina0, douta0, clkb, enb, web, addrb, dinb, doutb0); assign clka=clk_cog; assign ena = ena_bus; //assign ram_q0=douta0; assign dina0[7:0] =d[7:0]; assign wea0= (ena_bus && w && wb[0]); assign addra[13:0] = a[13:0]; assign clkb=sx[0]; assign enb=1'b0; assign web=1'b0; assign addrb = a2; assign dinb = 8'b0; assign blue=doutb0;//a2[7:0];//doutb0; wire wea1; wire [7:0] dina1; wire [7:0] douta1; wire [7:0] dinb1; wire [7:0] doutb1; blk_mem_gen_1 ram1(clka, ena, wea1, addra, dina1, douta1, clkb, enb, web, addrb, dinb, doutb1); //assign ram_q1=douta1; assign dina1[7:0] =d[15:8]; assign wea1= (ena_bus && w && wb[1]); wire wea2; wire [7:0] dina2; wire [7:0] douta2; wire [7:0] dinb2; wire [7:0] doutb2; blk_mem_gen_2 ram2(clka, ena, wea2, addra, dina2, douta2, clkb, enb, web, addrb, dinb, doutb2); //assign ram_q2=douta2; assign dina2[7:0] =d[23:16]; assign wea2= (ena_bus && w && wb[2]); wire wea3; wire [7:0] dina3; wire [7:0] douta3; wire [7:0] dinb3; wire [7:0] doutb3; blk_mem_gen_3 ram3(clka, ena, wea3, addra, dina3, douta3, clkb, enb, web, addrb, dinb, doutb3); //assign ram_q3=douta3; assign dina3[7:0]=d[31:24]; assign wea3= (ena_bus && w && wb[3]); always @(posedge clk_cog) begin // if (ena_bus && w && wb[3]) // ram3[a[13:0]] <= d[31:24]; if (ena_bus) ram_q3 <= douta3;//ram3[a[13:0]]; end always @(posedge clk_cog) begin // if (ena_bus && w && wb[2]) // ram2[a[13:0]] <= d[23:16]; if (ena_bus) ram_q2 <= douta2; //ram2[a[13:0]]; end always @(posedge clk_cog) begin // if (ena_bus && w && wb[1]) // ram1[a[13:0]] <= d[15:8]; if (ena_bus) ram_q1 <= douta1;//ram1[a[13:0]]; end always @(posedge clk_cog) begin // if (ena_bus && w && wb[0]) // ram0[a[13:0]] <= d[7:0]; if (ena_bus) ram_q0 <= douta0; //ram0[a[13:0]]; end assign q = {ram_q3, ram_q2, ram_q1, ram_q0}; */ ///////////////////////////////////////////////////////////////////////////////////////////////// // 16KB x 32 (64KB) ram with byte-write enables ($0000..$FFFF) reg [7:0] ram3 [16*1024-1:0]; // 4 x 16KB reg [7:0] ram2 [16*1024-1:0]; reg [7:0] ram1 [16*1024-1:0]; reg [7:0] ram0 [16*1024-1:0]; // pre-load ROM initial begin //Upper part of ROM (booter, interpreter, copyright, runner) @ 0xF004/4 $readmemh ("ROM_$F004-$FFFF_BYTE_0.hex", ram0, 15*1024+1); $readmemh ("ROM_$F004-$FFFF_BYTE_1.hex", ram1, 15*1024+1); $readmemh ("ROM_$F004-$FFFF_BYTE_2.hex", ram2, 15*1024+1); $readmemh ("ROM_$F004-$FFFF_BYTE_3.hex", ram3, 15*1024+1); //Font @ 0x8000/4 $readmemh ("rom_8000_bfff_font_0.hex", ram0, 8192); $readmemh ("rom_8000_bfff_font_1.hex", ram1, 8192); $readmemh ("rom_8000_bfff_font_2.hex", ram2, 8192); $readmemh ("rom_8000_bfff_font_3.hex", ram3, 8192); //Log table @ 0xc000/4 $readmemh ("rom_c000_cfff_log_0.hex", ram0, 12288); $readmemh ("rom_c000_cfff_log_1.hex", ram1, 12288); $readmemh ("rom_c000_cfff_log_2.hex", ram2, 12288); $readmemh ("rom_c000_cfff_log_3.hex", ram3, 12288); //Anti-log table @ 0xD000/4 $readmemh ("rom_d000_dfff_antilog_0.hex", ram0, 13312); $readmemh ("rom_d000_dfff_antilog_1.hex", ram1, 13312); $readmemh ("rom_d000_dfff_antilog_2.hex", ram2, 13312); $readmemh ("rom_d000_dfff_antilog_3.hex", ram3, 13312); //Sine table @ 0xE000/4 $readmemh ("rom_e000_f003_sine_0.hex", ram0, 14336); $readmemh ("rom_e000_f003_sine_1.hex", ram1, 14336); $readmemh ("rom_e000_f003_sine_2.hex", ram2, 14336); $readmemh ("rom_e000_f003_sine_3.hex", ram3, 14336); end reg [7:0] ram_q3; reg [7:0] ram_q2; reg [7:0] ram_q1; reg [7:0] ram_q0; always @(posedge clk_cog) begin if (ena_bus && w && wb[3]) ram3[a[13:0]] <= d[31:24]; if (ena_bus) ram_q3 <= ram3[a[13:0]]; end always @(posedge clk_cog) begin if (ena_bus && w && wb[2]) ram2[a[13:0]] <= d[23:16]; if (ena_bus) ram_q2 <= ram2[a[13:0]]; end always @(posedge clk_cog) begin if (ena_bus && w && wb[1]) ram1[a[13:0]] <= d[15:8]; if (ena_bus) ram_q1 <= ram1[a[13:0]]; end always @(posedge clk_cog) begin if (ena_bus && w && wb[0]) ram0[a[13:0]] <= d[7:0]; if (ena_bus) ram_q0 <= ram0[a[13:0]]; end assign q = {ram_q3, ram_q2, ram_q1, ram_q0}; //////////////////////////////////////////////////////////////// //local copy of rom font reg [31:0] font [4096-1:0]; //rom_8000_bfff_font.hex // pre-load Font initial begin $readmemh ("rom_8000_bfff_font.hex", font, 0); end //wire [7:0] c; //wire [31:0] char; //assign char = {ram3[8192+sx/32],ram2[8192+sx/32],ram1[8192+sx/32],ram0[8192+sx/32]}; //assign c= (char[sx%32] == 1) ? 8'hFF : 8'h00; //note: blue and red wires currently swapped //assign red = (sy < 240) ? 8'h00 : 8'hFF;;//{8{b0 | b1 | b5}} + {2'b0,{6{b6}}} + {b7, 7'b0}; //assign green = 8'hFF;//{8{b1 | b2 | b3}} + {2'b0,{6{b6}}} + {b7, 7'b0}; //assign blue = 8'h00;//{8{b3 | b4 | b5}} + {2'b0,{6{b6}}} + {b7, 7'b0}; //New Scheme: one long per tile, lower 8 bits are tile#, upper 24 bits are 4 sets of 6 color bits //Newer scheme: one word per tile, lower 8 bits are character#, upper 8 bits are colorset index wire signed [15:0] sx2 = sx+32+1; reg [7:0] char0; reg [7:0] char1; reg [7:0] char2; reg [7:0] char3; // initial // char = 8'h41; //A==41 reg [13:0] pScreen; initial pScreen = 'h1C00; always @(posedge pix_clk) begin if ((sx2>0) &&((sx2%32) == 24)) //pScreen <= 'h1C00+sx2/32 +(sy/16)*20; //40 cols at VGA resolution = 20 longs pScreen <= 'h1C00+sx2/32 +(sy/16)*40; //80 cols at 720p resolution = 40 longs end always @(posedge pix_clk) begin if ((sx2>0) &&((sx2%32) == 27)) char0 <= ram0[pScreen];//8'h43; //A==41 //ram0['h1C00]; 8'h41; //A==41 end always @(posedge pix_clk) begin if ((sx2>0) &&((sx2%32) == 27)) char1 <= ram1[pScreen]; end always @(posedge pix_clk) begin if ((sx2>0) &&((sx2%32) == 27)) char2 <= ram2[pScreen]; end always @(posedge pix_clk) begin if ((sx2>0) &&((sx2%32) == 27)) char3 <= ram3[pScreen]; end reg [7:0] color0; reg [7:0] color1; always @(posedge pix_clk) begin if ((sx2%32) == 31) color0<=char1; end always @(posedge pix_clk) begin if ((sx2%32) == 31) color1<=char3; end // wire [5:0] color3 = char3[7:2]; // wire [5:0] color2 = {char3[1:0],char2[7:4]}; // wire [5:0] color1 = {char2[3:0],char1[7:6]}; // wire [5:0] color0 = char1[5:0]; wire [13:0] pBase0 = char0<<4; //char0<<4;//((((char1<<8) +char0)<<6) -'h8000)/4; //4 because we have a table of longs wire [13:0] pBase1 = char2<<4; //screen lower 10 bits = `h252 should point to R&S //Need to multiply by 64 and then subtract 'h8000 to get good byte pointer, then divide by 4 to get long pointer reg [13:0] pFont0; reg [13:0] pFont1; always @(posedge pix_clk) begin if ((sx2%32) == 29) pFont0<= pBase0+ sy[3:0];//(sy%16); end always @(posedge pix_clk) begin if ((sx2%32) == 29) pFont1<= pBase1+ sy[3:0];//(sy%16); end reg [63:0] bits; always @(posedge pix_clk) begin if ((sx2%32) == 31) //last pixel in char? //((sx % 16) == 15) //last pixel in char? bits <= {font[pFont1],font[pFont0]}; end reg [7:0] ramb; reg [7:0] ramg; reg [7:0] ramr; assign blue = ramb; assign green = ramg; assign red = ramr; wire [1:0] pixel; assign pixel = bits >> ((sx2%32)*2); //'h00FF00FF or 0000FFFF for white on black reg [31:0] reds [255:0]; reg [31:0] greens [255:0]; reg [31:0] blues [255:0]; initial begin //white on black reds[0]= 'h00FF00FF; //back, fore, back, fore greens[0] ='h00FF00FF; blues[0] = 'h00FF00FF; reds[1]= 'h0000FFFF; //back, back, fore, fore greens[1] ='h0000FFFF; blues[1] = 'h0000FFFF; //yellow on dark blue reds[2]= 'h00FF00FF; blues[2] = 'h80008000; greens[2] ='h00FF00FF; reds[3]= 'h0000FFFF; blues[3] = 'h80800000; greens[3] ='h0000FFFF; //long $FF20FF20 'green/white reds[4]= 'h00FF00FF; blues[4] = 'h00FF00FF; greens[4] ='hFFFFFFFF; reds[5]= 'h0000FFFF; blues[5] = 'h0000FFFF; greens[5] ='hFFFFFFFF; //yellow on dark blue reds[6]= 'h00000000; blues[6] = 'h80008000; greens[6] ='h00FF00FF; reds[7]= 'h00000000; blues[7] = 'h80800000; greens[7] ='h0000FFFF; //red/white reds[8]= 'h80FF80FF; //back, fore, back, fore blues[8] = 'h00FF00FF; greens[8] ='h00FF00FF; reds[9]= 'h8080FFFF; //back, back, fore, fore blues[9] = 'h0000FFFF; greens[9] ='h0000FFFF; reds[10] = 'h00000000; greens[10] = 'hFFFF60A0; blues[10] = 'h00000000; end /* long $C000C000 'red long $C0C00000 long $08A808A8 'green long $0808A8A8 long $50005000 'blue long $50500000 long $FC00FC00 'white long $FCFC0000 long $FF80FF80 'red/white --> white, med red, white, med red long $FFFF8080 long $FF20FF20 'green/white long $FFFF2020 long $FF28FF28 'cyan/white long $FFFF2828 long $00A800A8 'grey/black long $0000A8A8 long $C0408080 'redbox spcl long $30100020 'greenbox -->green, med red, black, med green long $3C142828 'cyanbox long $FC54A8A8 'greybox long $3C14FF28 'cyanbox+underscore */ wire [31:0] red0 = reds[color0]; wire [31:0] green0 = greens[color0]; wire [31:0] blue0 = blues[color0]; wire [31:0] red1 = reds[color1]; wire [31:0] green1 = greens[color1]; wire [31:0] blue1 = blues[color1]; always @(posedge pix_clk) begin if ((sx2%32)<16) begin //white or magenta rgb(255,0,255) if (pixel== 2'b00) begin ramr <= red0[31:24];//(color0 == 0) ? 8'h00 : 8'h00;//{color0[5:4],color0[5:4],color0[5:4],color0[5:4]};//8'hFF; ramg <= green0[31:24];//(color0 == 0) ? 8'h00 : 8'h00;//8'h00;//{color0[3:2],color0[3:2],color0[3:2],color0[3:2]};//8'hFF; ramb <= blue0[31:24];//(color0 == 0) ? 8'h00 : 8'h00;//8'hFF;//{color0[1:0],color0[1:0],color0[1:0],color0[1:0]};//8'hFF; end if (pixel== 2'b01) begin ramr <= red0[23:16];//(color0 == 0) ? 8'hFF : 8'h00;//8'hFF;//{color1[5:4],color1[5:4],color1[5:4],color1[5:4]};//8'hFF; ramg <= green0[23:16];//(color0 == 0) ? 8'hFF : 8'h00;//8'h0F;//{color1[3:2],color1[3:2],color1[3:2],color1[3:2]};//8'hFF; ramb <= blue0[23:16];//(color0 == 0) ? 8'hFF : 8'h00;//8'h0F;//{color1[1:0],color1[1:0],color1[1:0],color1[1:0]};//8'hFF; end if (pixel== 2'b10) begin ramr <= red0[15:8];//(color0 == 0) ? 8'h00 : 8'hFF;//8'hFF;//{color2[5:4],color2[5:4],color2[5:4],color2[5:4]};//8'hFF; ramg <= green0[15:8];//(color0 == 0) ? 8'h00 : 8'hFF;//8'hF0;//{color2[3:2],color2[3:2],color2[3:2],color2[3:2]};//8'hFF; ramb <= blue0[15:8];//(color0 == 0) ? 8'h00 : 8'hFF;//8'hF0;//{color2[1:0],color2[1:0],color2[1:0],color2[1:0]};//8'hFF; end if (pixel== 2'b11) begin ramr <= red0[7:0];//(color0 == 0) ? 8'hFF : 8'hFF;//8'hFF;//{color3[5:4],color3[5:4],color3[5:4],color3[5:4]};//8'hFF; ramg <= green0[7:0];//(color0 == 0) ? 8'hFF : 8'hFF;//8'hFF;//{color3[3:2],color3[3:2],color3[3:2],color3[3:2]};//8'hFF; ramb <= blue0[7:0];//(color0 == 0) ? 8'hFF : 8'hFF;//8'h00;// {color3[1:0],color3[1:0],color3[1:0],color3[1:0]};//8'hFF; end end else //teal rgb(0,128,128) or yellow rgb(255,255,0) begin if (pixel== 2'b00) begin ramr <= red1[31:24];//(color0 == 0) ? 8'h00 : 8'h00;//{color0[5:4],color0[5:4],color0[5:4],color0[5:4]};//8'hFF; ramg <= green1[31:24];//(color0 == 0) ? 8'h00 : 8'h00;//8'h00;//{color0[3:2],color0[3:2],color0[3:2],color0[3:2]};//8'hFF; ramb <= blue1[31:24];//(color0 == 0) ? 8'h00 : 8'h00;//8'hFF;//{color0[1:0],color0[1:0],color0[1:0],color0[1:0]};//8'hFF; end if (pixel== 2'b01) begin ramr <= red1[23:16];//(color0 == 0) ? 8'hFF : 8'h00;//8'hFF;//{color1[5:4],color1[5:4],color1[5:4],color1[5:4]};//8'hFF; ramg <= green1[23:16];//(color0 == 0) ? 8'hFF : 8'h00;//8'h0F;//{color1[3:2],color1[3:2],color1[3:2],color1[3:2]};//8'hFF; ramb <= blue1[23:16];//(color0 == 0) ? 8'hFF : 8'h00;//8'h0F;//{color1[1:0],color1[1:0],color1[1:0],color1[1:0]};//8'hFF; end if (pixel== 2'b10) begin ramr <= red1[15:8];//(color0 == 0) ? 8'h00 : 8'hFF;//8'hFF;//{color2[5:4],color2[5:4],color2[5:4],color2[5:4]};//8'hFF; ramg <= green1[15:8];//(color0 == 0) ? 8'h00 : 8'hFF;//8'hF0;//{color2[3:2],color2[3:2],color2[3:2],color2[3:2]};//8'hFF; ramb <= blue1[15:8];//(color0 == 0) ? 8'h00 : 8'hFF;//8'hF0;//{color2[1:0],color2[1:0],color2[1:0],color2[1:0]};//8'hFF; end if (pixel== 2'b11) begin ramr <= red1[7:0];//(color0 == 0) ? 8'hFF : 8'hFF;//8'hFF;//{color3[5:4],color3[5:4],color3[5:4],color3[5:4]};//8'hFF; ramg <= green1[7:0];//(color0 == 0) ? 8'hFF : 8'hFF;//8'hFF;//{color3[3:2],color3[3:2],color3[3:2],color3[3:2]};//8'hFF; ramb <= blue1[7:0];//(color0 == 0) ? 8'hFF : 8'hFF;//8'h00;// {color3[1:0],color3[1:0],color3[1:0],color3[1:0]};//8'hFF; end /* if (pixel== 2'b00) begin ramr <= (color1 == 0) ? 8'h00 : 8'h00;//8'h00;//{color0[5:4],color0[5:4],color0[5:4],color0[5:4]};//8'hFF; ramg <= (color1 == 0) ? 8'h00 : 8'h00;//8'h00;//{color0[3:2],color0[3:2],color0[3:2],color0[3:2]};//8'hFF; ramb <= (color1 == 0) ? 8'h00 : 8'h00;//8'hFF;//{color0[1:0],color0[1:0],color0[1:0],color0[1:0]};//8'hFF; end if (pixel== 2'b01) begin ramr <= (color1 == 0) ? 8'hFF : 8'h00;//8'hFF;//{color1[5:4],color1[5:4],color1[5:4],color1[5:4]};//8'hFF; ramg <= (color1 == 0) ? 8'hFF : 8'h00;//8'h0F;//{color1[3:2],color1[3:2],color1[3:2],color1[3:2]};//8'hFF; ramb <= (color1 == 0) ? 8'hFF : 8'h00;//8'h0F;//{color1[1:0],color1[1:0],color1[1:0],color1[1:0]};//8'hFF; end if (pixel== 2'b10) begin ramr <= (color1 == 0) ? 8'h00 : 8'hFF;//8'hFF;//{color2[5:4],color2[5:4],color2[5:4],color2[5:4]};//8'hFF; ramg <= (color1 == 0) ? 8'h00 : 8'hFF;//8'hF0;//{color2[3:2],color2[3:2],color2[3:2],color2[3:2]};//8'hFF; ramb <= (color1 == 0) ? 8'h00 : 8'hFF;//8'hF0;//{color2[1:0],color2[1:0],color2[1:0],color2[1:0]};//8'hFF; end if (pixel== 2'b11) begin ramr <= (color1 == 0) ? 8'hFF : 8'hFF;//8'hFF;//{color3[5:4],color3[5:4],color3[5:4],color3[5:4]};//8'hFF; ramg <= (color1 == 0) ? 8'hFF : 8'hFF;//8'hFF;//{color3[3:2],color3[3:2],color3[3:2],color3[3:2]};//8'hFF; ramb <= (color1 == 0) ? 8'hFF : 8'hFF;//8'h00;// {color3[1:0],color3[1:0],color3[1:0],color3[1:0]};//8'hFF; end */ end end // reg [13:0] a2; // initial a2[13:0] =14'h8000; // always @(posedge pix_clk) // begin // a2[13:0] <= 'h2000 + sx +sy;// 14'h2000;//sx[14:0]; //// if (a2[13:0] < 14'h9000) //// a2[13:0] <= a2[13:0] +1; //// else //// a2[13:0] <=14'h8000; // end // reg [7:0] ramb; // reg [7:0] ramg; // reg [7:0] ramr; // always @(posedge pix_clk) // begin // ramb<=ram0[a2[13:0]];//ram0[sx[8:1]];//a2[7:0];//ram0[a2[13:0]]; // end //assign blue=ramb;//sx[8:1];//ramb; endmodule