use(channels). decoder_delay:expr(int)=10. execute_delay:expr(int)=10. prefetch_cycle:expr(int)=10. instr_type : type = int. opcode_type : type = scalar. op_add : val(opcode_type). op_sub : val(opcode_type). op_mul : val(opcode_type). op_div : val(opcode_type). regnum_type : type = int. dec_instr_type : type = record ( opcode :: opcode_type, reg1 :: regnum_type, reg2 :: regnum_type ). decode(i:val(instr_type)):expr(dec_instr_type)=( di:var(dec_instr_type). di->opcode := ( case ((i and 16#300)>>8) when 0 => op_mul when 1 => op_add when 2 => op_div when 3 => op_sub ); di->reg1 := cast(regnum_type,(i and 16#0F0)>>4); di->reg2 := cast(regnum_type,i and 16#00F); di ). decoder_block(i:var(chan(instr_type)), o:var(chan(dec_instr_type))):expr(void)=( forever( i?( wait_for(decoder_delay); o!decode(?i) ) ) ). source_block(o:var(chan(instr_type))):expr(void)=( forever( o!(cast(instr_type,rand(16#400))) | wait_for(prefetch_cycle) ) ). sink_block(i:var(chan(dec_instr_type))):expr(void)=( forever( i?( wait_for(execute_delay) ) ) ). I:var(chan(instr_type)). DI:var(chan(dec_instr_type)). init_chan(I,"Instructions"); init_chan(DI,"Decoded instructions"); ( source_block(I) | decoder_block(I,DI) | sink_block(DI) )