在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 5720|回复: 4

[原创] 求购PIC内核

[复制链接]
发表于 2020-3-2 10:48:49 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
求购PIC内核,16位或14位指令宽度。
qq:447595064
发表于 2022-7-18 10:48:04 | 显示全部楼层
有点意思
发表于 2022-7-23 07:26:05 | 显示全部楼层
本帖最后由 轩辕志瑜 于 2022-7-23 08:47 编辑

呐, 给你一个. 只是核心模块非完整mcu

核心模块
module pic16f1826(clk,rst,w_q);
  input clk , rst;
  output reg [7:0] w_q;
  reg [10:0] pc , mar , adr_in , pc_in;
  reg [13:0] data,IR;
  wire [13:0] rom_out;
  reg [2:0] ps , ns ,sel_pc;
  wire [2:0] sel_bit;
  wire [7:0] ir_out,ram_out;
  reg [7:0] alu_q,mux1_out,databus,ram_mux,bcf_mux,bsf_mux,port_b_out; //Port_b_out????????
  reg[3:0] op,stk_ptr;
  reg load_pc,load_mar ,load_ir,load_w,ram_en,sel_alu,sel_bus,load_port_b,push,pop,reset_ir;
  reg [1:0] sel_ram_mux;
  wire btfsc_btfss_skip_bit,btfss_skip_bit,btfsc_skip_bit;
  wire [10:0] stack_out,stack_in;
  wire [3:0] stk_index;
  reg [10:0] stack [15:0];
  wire [10:0] w_change,k_change;
  single_port_ram_128x8 ram(.data(databus),.addr(ir_out[6:0]),.clk(clk),.q(ram_out),.en(ram_en)); //RAM

  always@(adr_in) //ROM??
  begin
  case(adr_in)
              11'h0 : data = 14'h0103;
                11'h1 : data = 14'h01A5;
                11'h2 : data = 14'h3003;
                11'h3 : data = 14'h00A5;
                11'h4 : data = 14'h3000;
                11'h5 : data = 14'h3E01;
                11'h6 : data = 14'h0BA5;
                11'h7 : data = 14'h2805;
                11'h8 : data = 14'h2808;
                11'h9 : data = 14'h3400;
                11'ha : data = 14'h3400;
                default: data = 14'h0;
endcase
end
//?????bit
assign MOVLW = {IR[13:8]==6'b11_0000};
assign ADDLW = {IR[13:8]==6'b11_1110};
assign IORLW = {IR[13:8]==6'b11_1000};
assign ANDLW = {IR[13:8]==6'b11_1001};
assign SUBLW = {IR[13:8]==6'b11_1100};
assign XORLW = {IR[13:8]==6'b11_1010};
assign CLRF = {IR[13:7]==7'b00_00011};
assign CLRW = {IR[13:2]==12'b000001000000};
assign GOTO = {IR[13:11]==3'b101};
assign ADDWF = {IR[13:8]==6'b00_0111};
assign ANDWF = {IR[13:8]==6'b00_0101};
assign COMF = {IR[13:8]==6'b00_1001};
assign DECF = {IR[13:8]==6'b00_0011};

assign DECFSZ = {IR[13:8] == 6'b001011};
assign INCFSZ = {IR[13:8] == 6'b001111};

assign INCF = {IR[13:8]==6'b00_1010};
assign IORWF = {IR[13:8]==6'b00_0100};
assign MOVF = {IR[13:8]==6'b00_1000};
assign MOVWF = {IR[13:7]==7'b00_00001};
assign SUBWF = {IR[13:8]==6'b00_0010};
assign XORWF = {IR[13:8]==6'b00_0110};
assign alu_zero = (alu_q == 0) ? 1'b1 : 1'b0;
assign BCF = {IR[13:10]==4'b0100};
assign BSF = {IR[13:10]==4'b0101};
assign sel_bit = IR[9:7];
assign rom_out = data;
assign BTFSC = {IR[13:10] == 4'b0110};
assign BTFSS = {IR[13:10] == 4'b0111};
assign btfsc_skip_bit = ram_out[IR[9:7]] == 0;
assign btfss_skip_bit = ram_out[IR[9:7]] == 1;
assign btfsc_btfss_skip_bit = (BTFSC & btfsc_skip_bit) | (BTFSS & btfss_skip_bit);
assign addr_port_b = (IR[6:0] == 7'h0d);
assign ASRF = {IR[13:8]==6'b11_0111};
assign LSLF = {IR[13:8]==6'b11_0101};
assign LSRF = {IR[13:8]==6'b11_0110};
assign RLF = {IR[13:8]==6'b00_1101};
assign RRF = {IR[13:8]==6'b00_1100};
assign SWAPF = {IR[13:8]==6'b00_1110};
assign BRA = {IR[13:9]==5'b11_001};
assign BRW = {IR[13:0]==14'b00000000001011};

assign CALL = {IR[13:11] == 3'b100};
assign RETURN = {IR[13:0] == 14'b00000000001000};
assign NOP = {IR[13:0] == 14'b00000000000000};

assign stk_index = stk_ptr + 1;
assign stack_out = stack[stk_ptr[3:0]];
assign stack_in = pc;
assign w_change = {3'b0,w_q} - 1;
assign k_change = {IR[8],IR[8],IR[8:0]} - 1;

always@(posedge clk)
begin
  if(rst)
    stk_ptr = 4'b1111;
else if(push)
  begin
  stack[stk_index[3:0]] <= stack_in;
  stk_ptr <= stk_ptr + 1;  
  end
  else if(pop)
    stk_ptr <= stk_ptr - 1;
end

always@(posedge clk)
begin
  if(rst) port_b_out <= 0;
  else if(load_port_b) port_b_out <= databus;
end

always@(*) //ram_mux????
begin
  case(sel_ram_mux)
    0 : ram_mux  = ram_out;
    1 : ram_mux = bcf_mux;
    2 : ram_mux = bsf_mux;
    default : ram_mux = 8'bx;
  endcase
end

always@(*) //??bcf_mux???
begin
  case(sel_bit)
    3'b000 : bcf_mux  = ram_out & 8'hFE;
    3'b001 : bcf_mux  = ram_out & 8'hFD;
    3'b010 : bcf_mux  = ram_out & 8'hFB;
    3'b011 : bcf_mux  = ram_out & 8'hE7;
    3'b100 : bcf_mux  = ram_out & 8'hEF;
    3'b101 : bcf_mux  = ram_out & 8'hDF;
    3'b110 : bcf_mux  = ram_out & 8'hBF;
    3'b111 : bcf_mux  = ram_out & 8'h7F;
  
  endcase
end

always@(*) //??bsf_mux???
begin
  case(sel_bit)
    3'b000 : bsf_mux  = ram_out | 8'h01;
    3'b001 : bsf_mux  = ram_out | 8'h02;
    3'b010 : bsf_mux  = ram_out | 8'h04;
    3'b011 : bsf_mux  = ram_out | 8'h08;
    3'b100 : bsf_mux  = ram_out | 8'h10;
    3'b101 : bsf_mux  = ram_out | 8'h20;
    3'b110 : bsf_mux  = ram_out | 8'h40;
    3'b111 : bsf_mux  = ram_out | 8'h80;
  endcase
end

always@(posedge clk) //?????ns
  begin
    if(rst) ps <= 3'b000;
    else ps <= ns;
end


always@(*)
begin
  if(sel_bus)
    databus = w_q;
  else
    databus = alu_q;
end


always@(*) //??
begin
  sel_pc = 0;
  ram_en = 0;
  load_pc = 0;
  load_mar = 0;
  load_ir = 0;
  load_w = 0;
  sel_alu = 0;
  sel_bus = 0;
  sel_ram_mux = 0;
  load_port_b = 0;
  push = 0;
  reset_ir = 0;
  pop = 0;
  case(ps)
    3'b000 : begin
      ns = 3'b001;
    end
    3'b001 : begin //T1
      ns = 3'b010;
      load_mar = 1;
    end
    3'b010 : begin //T2
      ns = 3'b011;
      load_pc = 1;
    end
    3'b011 : begin //T3
      ns = 3'b100;
      load_ir = 1;
    end
    3'b100 : begin //T4
    load_mar = 1;
    sel_pc = 2'b00;
    load_pc = 1;
      if(MOVLW | ADDLW | IORLW | ANDLW | SUBLW | XORLW)
        begin
      load_w = 1;
      if(MOVLW)
        op = 0;
   else if(ADDLW)
        op = 1;
   else if(IORLW)
        op = 4;
   else if(ANDLW)
        op = 3;
    else if(SUBLW)
        op = 2;
    else if(XORLW)
        op = 5;
   end
     if(ADDWF)
     begin
       op = 1;
       sel_alu = 1;
       if(ir_out[7])
         ram_en = 1;
       else
         load_w = 1;
     end
     if(ANDWF)
     begin
       op = 3;
       sel_alu = 1;
       if(ir_out[7])
         ram_en = 1;
       else
         load_w = 1;
     end
     if(CLRF)
       begin
         op = 8;
         sel_alu = 1;
         ram_en = 1;
       end
       if(CLRW)
       begin
         op = 8;
         sel_alu = 1;
         load_w = 1;
       end
        if(COMF)
       begin
         op = 9;
         sel_alu = 1;
         ram_en = 1;
       end
        if(DECF)
       begin
         op = 7;
         sel_alu = 1;
         ram_en = 1;
       end
       if(INCF)
         begin
           op = 6;
           sel_alu = 1;
           if(ir_out[7])
             ram_en = 1;
           else
             load_w = 1;
         end
         if(IORWF)
         begin
           op = 4;
           sel_alu = 1;
           if(ir_out[7])
             ram_en = 1;
           else
             load_w = 1;
         end
         
        if(MOVWF)
         begin
         sel_bus = 1;
         if(addr_port_b)
           load_port_b = 1;
         else
           ram_en = 1;
         end
         
         if(MOVF)
         begin
             op = 0;
           sel_alu = 1;
           if(ir_out[7])
             ram_en = 1;
           else
             load_w = 1;
         end
         if(XORWF)
         begin
           op = 5;
           sel_alu = 1;
             if(ir_out[7])
             ram_en = 1;
           else
             load_w = 1;
         end
         if(SUBWF)
         begin
           op = 2;
           sel_alu = 1;
             if(ir_out[7])
             ram_en = 1;
           else
             load_w = 1;
         end

            if(BCF)
            begin
              sel_alu= 1;
              sel_ram_mux = 1;
              op = 0;
              sel_bus= 0;
              ram_en= 1;
            end  
            
            if(BSF)
              begin
              sel_alu= 1;
              sel_ram_mux = 2;
              op = 0;
              sel_bus= 0;
              ram_en= 1;
              end

              if(ASRF)
                begin
                  sel_alu = 1;
                  sel_ram_mux = 0;
                  op = 4'hA;
                  if(ir_out[7])
                    begin
                      sel_bus = 0;
                      ram_en = 1;
                    end
                  else
                    load_w = 1;
                end
               
              if(LSLF)
                begin
                  sel_alu = 1;
                  sel_ram_mux = 0;
                  op = 4'hB;
                  if(ir_out[7])
                    begin
                      sel_bus = 0;
                      ram_en = 1;
                    end
                  else
                    load_w = 1;
                end
               
              if(LSRF)
                begin
                  sel_alu = 1;
                  sel_ram_mux = 0;
                  op = 4'hC;
                  if(ir_out[7])
                    begin
                      sel_bus = 0;
                      ram_en = 1;
                    end
                  else
                    load_w = 1;
                end
               
                if(RLF)
                begin
                  sel_alu = 1;
                  sel_ram_mux = 0;
                  op = 4'hD;
                  if(ir_out[7])
                    begin
                      sel_bus = 0;
                      ram_en = 1;
                    end
                  else
                    load_w = 1;
                end
               
                if(RRF)
                begin
                  sel_alu = 1;
                  sel_ram_mux = 0;
                  op = 4'hE;
                  if(ir_out[7])
                    begin
                      sel_bus = 0;
                      ram_en = 1;
                    end
                  else
                    load_w = 1;
                end
               
                if(SWAPF)
                begin
                  sel_alu = 1;
                  sel_ram_mux = 0;
                  op = 4'hF;
                  if(ir_out[7])
                    begin
                      sel_bus = 0;
                      ram_en = 1;
                    end
                  else
                    load_w = 1;
                end
               
                if(CALL)
                  begin
                    push = 1;
                  end

                    if(NOP)
                      begin
                      end

   ns = 3'b101;
    end
   
    3'b101 : begin
      if(BRW)
                    begin
                      load_pc = 1;
                      sel_pc = 3'b100;
                    end
         if(BRA)
                    begin
                      load_pc = 1;
                      sel_pc = 3'b011;
                    end
      if(GOTO)
        begin
          sel_pc = 2'b01;
          load_pc = 1;
        end
        if(CALL)
          begin
             sel_pc = 2'b01;
             load_pc = 1;
          end
            if(RETURN)
                  begin
                    sel_pc = 3'b010;
                    load_pc = 1;
                    pop = 1;
                  end
      ns = 3'b110;
    end

    3'b110 : begin
      load_ir = 1;
      if(BRW)
                    begin
                      reset_ir = 1;
                    end
         if(BRA)
                    begin
                      reset_ir = 1;
                    end
      if(BTFSC | BTFSS)
              begin
                if(btfsc_btfss_skip_bit == 1)
                  begin
                   reset_ir = 1;
                  end
              end
      if(INCFSZ)
            begin
            op = 6;
            sel_alu = 1;
             if(ir_out[7])
               begin
                 ram_en = 1;
                 sel_bus = 0;
               if(alu_zero)
               begin
               reset_ir = 1;
               end  
               end
             else
               begin
               load_w = 1;
               if(alu_zero)
                  begin
                  load_pc = 1;
                  sel_pc = 0;
                  end  
               end
            end   
      
      if(DECFSZ)
           begin
           op = 7;
           sel_alu = 1;
          if(alu_zero)
             begin
              reset_ir = 1;
             end
           if(ir_out[7])
               begin
                ram_en = 1;
                sel_bus = 0;  
             end
            else  
            begin
            load_w = 1;               
            end
          end
         
      if(GOTO)
        begin
          reset_ir = 1;
        end
         if(CALL)
          begin
             reset_ir = 1;
          end
          if(RETURN)
                  begin
                    reset_ir = 1;
                  end
      ns = 3'b100;
    end
  endcase
end

assign ir_out = IR;

always@(posedge clk)
begin
  if(rst) pc <= 11'b0000000000;
    else if(load_pc) pc<= pc_in;
  end

  always@(posedge clk)
begin
  if(rst) mar <= 11'b0000000000;
    else if(load_mar) mar <= pc;
  end

  always@(posedge clk)
begin
  adr_in <= mar;
  end

always@(posedge clk)
begin
  if(reset_ir) IR <= 14'b0000000000000;
    else if(load_ir) IR<= rom_out;
  end

  always@(posedge clk)
begin
  if(load_w) w_q <= alu_q;
  end

  always@(*) //PC???
  begin
    if(sel_pc == 3'b001)
      pc_in = ir_out;
    else if(sel_pc == 3'b000)
      pc_in = pc + 1;
    else if(sel_pc == 3'b010)
      pc_in = stack_out;
    else if(sel_pc == 3'b011)
      pc_in = pc + k_change;
    else if(sel_pc == 3'b100)
      pc_in = pc + w_change;
  end

  always@(*) //ALU???
  begin
    if(sel_alu)
      mux1_out = ram_mux;
    else
      mux1_out = ir_out;
  end

  always@(*) //ALU
  begin
    case(op)
      4'h0 : alu_q = mux1_out;
      4'h1 : alu_q = mux1_out + w_q;
      4'h2 : alu_q = mux1_out - w_q;
      4'h3 : alu_q = mux1_out & w_q;
      4'h4 : alu_q = mux1_out | w_q;
      4'h5 : alu_q = mux1_out ^ w_q;
      4'h6 : alu_q = mux1_out + 1;
      4'h7 : alu_q = mux1_out - 1;
      4'h8 : alu_q = 0;
      4'h9 : alu_q = ~mux1_out;
      4'hA : alu_q = {mux1_out[7], mux1_out[7:1]};
      4'hB : alu_q = {mux1_out[6:0], 1'b0};
      4'hC : alu_q = {1'b0, mux1_out[7:1]};
      4'hD : alu_q = {mux1_out[6:0],mux1_out[7]};
      4'hE : alu_q = {mux1_out[0],mux1_out[7:1]};
      4'hF : alu_q = {mux1_out[3:0],mux1_out[7:4]};
      default : alu_q = mux1_out + w_q;
      endcase
      end
endmodule
发表于 2022-7-23 08:32:26 | 显示全部楼层
本帖最后由 轩辕志瑜 于 2022-7-23 08:42 编辑

单口内存模块

module
single_port_ram_128x8
(
        input [7:0] data,
        input [5:0] addr,
        input en, clk,
        output [7:0] q
);

        reg [7:0] ram[127:0];
        reg [5:0] addr_reg;
        
        always @ (posedge clk)
        begin
                if (en)
                        ram[addr] <= data;
               
                addr_reg <= addr;
               
        end

        assign q = ram[addr_reg];
        
endmodule
发表于 2022-7-23 08:38:27 | 显示全部楼层
本帖最后由 轩辕志瑜 于 2022-7-23 08:42 编辑

测试用例

module tb();
  reg clk,rst;
  wire [7:0] port_b_out;
  
pic16f1826 core(
  .clk(clk),
  .rst(rst),
  .w_q(port_b_out)
  );
  
  initial begin
    rst = 1;
    clk = 0;
    #30
    rst = 0;
  end
always #20 clk = ~clk;  
  
endmodule
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /2 下一条

×

小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-12-18 16:31 , Processed in 0.021177 second(s), 6 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表