文章目录
- 题目一:将一个串行执行的C语言算法转化为单拍完成的并行可综合verilog。
- 思路
- 代码
- 知乎数字芯片实验室
- 牛客讨论区
- 题目二:饮料售卖机
- 思路
- E课网
- 代码(牛客讨论区)
题目一:将一个串行执行的C语言算法转化为单拍完成的并行可综合verilog。
unsigned char cal_table_high_first(unsigned char value)
{unsigned char i ;
unsigned char checksum = value ; for (i=8;i>0;--i){if (check_sum & 0x80){check_sum = (check_sum<<1) ^ 0x31;}else{check_sum = (check_sum << 1);}}return check_sum;
}
思路
图片来源知乎https://zhuanlan.zhihu.com/p/69969288
代码
知乎数字芯片实验室
以下代码目前没看懂
verilog实现
module loop1(input clk,input rst_n,input [7:0] check_sum,output reg [7:0] check_sum_o
);
//reg [7:0] check_sum_o;
always @ (posedge clk or negedge rst_n)if (!rst_n)begincheck_sum_o <= 8'h0;endelsebegincheck_sum_o[7] <= check_sum[3]^check_sum[2]^check_sum[5];check_sum_o[6] <= check_sum[2]^check_sum[1]^check_sum[4]^check_sum[7];check_sum_o[5] <= check_sum[1]^check_sum[7]^check_sum[0]^check_sum[3]^check_sum[6];check_sum_o[4] <= check_sum[7]^check_sum[0]^check_sum[3]^check_sum[6];check_sum_o[3] <= check_sum[3]^check_sum[7]^check_sum[6];check_sum_o[2] <= check_sum[2]^check_sum[6]^check_sum[5];check_sum_o[1] <= check_sum[1]^check_sum[5]^check_sum[4]^check_sum[7];check_sum_o[0] <= check_sum[0]^check_sum[4]^check_sum[3]^check_sum[6];end
endmodule
tb
module loop1_tb;reg clk;reg rst_n;reg [7:0] check_sum;wire [7:0] check_sum_o;always #1 clk=~clk;initial beginclk = 0;rst_n = 0;#10 rst_n = 1;for (check_sum=0;check_sum<16;check_sum=check_sum+1) begin#2 //check_sum = i;$display ("check_sum = %h", check_sum_o);if (check_sum == 15) $stop;end//$stop;endloop1 loop1_i1(.clk(clk),.rst_n(rst_n),.check_sum(check_sum),.check_sum_o(check_sum_o));
endmodule
来源知乎https://zhuanlan.zhihu.com/p/69969288
牛客讨论区
.1.
module check_sum(clk, rst, value, checksum);input clk, rst;input [7 : 0] value;output reg [7 : 0] checksum;parameter word_size = 8;wire [7:0] checksum1;wire [7:0] checksum2;wire [7:0] checksum3;wire [7:0] checksum4;wire [7:0] checksum5; wire [7:0] checksum6;wire [7:0] checksum7;wire [7:0] checksum8;assign checksum1 = (value[word_size-1] == 1) ? ( (value<<1)^8'h31 ) : ( value<<1 );
assign checksum2 = (checksum1[word_size-1] == 1) ? ( (checksum1<<1)^8'h31 ) : ( checksum1<<1 );
assign checksum3 = (checksum2[word_size-1] == 1) ? ( (checksum2<<1)^8'h31 ) : ( checksum2<<1 );
assign checksum4 = (checksum3[word_size-1] == 1) ? ( (checksum3<<1)^8'h31 ) : ( checksum3<<1 );
assign checksum5 = (checksum4[word_size-1] == 1) ? ( (checksum4<<1)^8'h31 ) : ( checksum4<<1 );
assign checksum6 = (checksum5[word_size-1] == 1) ? ( (checksum5<<1)^8'h31 ) : ( checksum5<<1 );
assign checksum7 = (checksum6[word_size-1] == 1) ? ( (checksum6<<1)^8'h31 ) : ( checksum6<<1 );
assign checksum8 = (checksum7[word_size-1] == 1) ? ( (checksum7<<1)^8'h31 ) : ( checksum7<<1 );always @(posedge clk)beginif(rst) checksum <= 0;else checksum <= checksum8;endendmodule
module checksum #(parameter word_size = 8)(clk, rst, value, checksum);input clk, rst;input [word_size-1: 0] value;output reg [word_size-1: 0] checksum;integer i;always @(posedge clk)if(rst) checksum <= 0;else begin//checksum <= 0; 我觉得这句没有应该不影响checksum <= value;for(i=8; i>0; i=i-1) beginif(checksum[word_size-1] == 1)checksum <= (checksum<<1)^8'h31;else checksum <= checksum<<1;endend
endmodule
题目二:饮料售卖机
设计一个自动饮料售卖机,共有两种饮料,其中饮料 A 每个 10 分钱,饮料 B 每个 5 分钱,硬币有 5 分和 10 分两种,并考虑找零。
要求用状态机实现,定义状态,画出状态转移图,并用 Verilog 完整描述该识别模块
思路
售卖机有五种工作状态:闲置、卖5分饮料、卖10分饮料、找零、不找零
输入有三种状态:闲置、按键5分、按键10分、收钱5分,收钱10分
输入:clk,rst,a,b,c
c=0售货机处于闲置状态,c=1售卖状态;c=1,a=0选5分的饮料,c=1,a=1选10分的饮料;b=0售货机收5分钱,b=1收10分钱
输出:state,x,y,k
x=1卖出10分的饮料,y=1卖出5分的饮料,k=1找零
中间寄存器:x,y,k,state
参数:Idle,sel,sel,reward,n_reward
E课网
代码(牛客讨论区)
module sel_machine(clk,rst,a,b,c,state,x,y,k);input clk,rst;input a,b,c; //c=1,a=0选5分的饮料,c=1,a=1选10分的饮料;//c=0售货机处于闲置状态,c=1售货机处于售卖状态;//b=0售货机收5分钱,b=1收10分钱output state,x,y,k;reg x,y,k; //x=1卖出10分的饮料,y=1卖出5分的饮料,k=1找零 reg [2:0] state; //不同状态的地址parameter Idle : 3'b1xx; //售货机处于闲置状态sel5: 3'b001; //售货机正在卖5分钱的饮料sel10:3'b010; //售货机正在卖10分钱的饮料reward:3'b011; //售货机找零n_reward:3'b000; //售货机不找零always @ (posedge clk) beginif (!rst) beginstate <= Idle;x <= 0;y <= 0;endelsecase(state)Idle:if(c=1)beginif(a) state <= sel10;else state <= sel5;endelse begin state <= Idle;x <= 0;y <= 0;endsel5: if(b)beginx <= 0;y <= 1; state <= reward;endelse beginx <= 0;y <= 1; state <= n_reward;endsel10: if(b) beginx <= 1;y <= 0; state <= n_reward;endelsebeginx <= 1;y <= 0; state <= Idle;endreward: beignk <= 1;state <= Idle;endn_reward: begink <= 0; state <= Idle;enddefault: state <= 3'b1xx;endcaseend
endmodule